0

我试图避免为@post 更新一个空名称。我是 RoR 的初学者,我不明白为什么在终端我得到了@post.invalid? => true,但在我看来edit.html.erb @post.invalid? => false

post_controller.rb

class PostsController < ApplicationController

  before_action :set_post, :only => [:edit, :show, :update, :destroy]

  def index
    @posts = Post.all
    respond_to do |format|
      format.html
      format.json { render json: @posts }
    end
  end

  def show
    respond_to do |format|
      format.html
      format.json { render json: @post }
    end
  end

  def edit
  end

  def update
    if @post.update(post_params)
      redirect_to posts_path, success: "Post updated"
    else
      puts @post.invalid? # write true
      render 'edit'
    end
  end

  def new
    @post = Post.new
  end

  def create
    post = Post.create(post_params) 
    redirect_to post_path(post.id), success: "Post created"
  end

  def destroy
    @post.destroy

    redirect_to posts_path, success: "Post deleted"
  end

  private

  def post_params
    params.require(:post).permit(:name, :content)
  end

  def set_post
    @post = Post.find(params[:id])
  end

end

post.rb

class Post < ApplicationRecord

  validates :name, presence: true

  def as_json(options = nil)
    super(only: [:name, :id, :created_at] )
  end
end

编辑.html.erb

<h1>Editer l´article</h1>

<%= @post.invalid? %> <!-- write false -->

<% if @post.invalid? %> <!-- return false -->
  <div class="alert alert-danger">
    <% @post.errors.full_messages.each do |message| %>
      <%= message %>
    <% end %>
  </div>
<% end %>

<%= form_for @post do |f| %>
  <div class="form-group">
    <label>Titre de l´article</label>
    <%= f.text_field :name, class: 'form-control' %>
  </div>
  <div class="form-group">
    <label>Contenu de l´article</label>
    <%= f.text_area :content, class: 'form-control' %>
  </div>
  <div class="form-group">
    <%= f.submit "Modifier l´article", class: 'btn btn-primary' %>
  </div>
<% end %>

我很困惑,有人有想法吗?

4

2 回答 2

1

这些方法valid?invalid?所有方法在每次调用时都会继续运行验证方法,因此可能会改变模型的状态。

如果您只想在验证已经运行时检查有效性,您应该改用@post.errors.present?or@post.errors.blank?永远不会改变状态,只读取现有错误(在调用update失败时添加到您的案例中。

此外(即使这里不是这种情况)在没有上下文的情况下调用valid?invalid?清除已添加验证的错误,例如validate ..., on: :update.

于 2022-02-01T00:33:08.820 回答
0

我找到的解决方案是@rewritten 的答案和这个的组合。

所以...

<h1>Editer l´article</h1>

<% if @post.errors.present? %>
  <div class="alert alert-danger">
    <% @post.errors.full_messages.each do |message| %>
      <%= message %>
    <% end %>
  </div>
<% end %>

<%= form_for @post, data: { turbo: false} do |f| %>
  <div class="form-group">
    <label>Titre de l´article</label>
    <%= f.text_field :name, class: 'form-control' %>
  </div>
  <div class="form-group">
    <label>Contenu de l´article</label>
    <%= f.text_area :content, class: 'form-control' %>
  </div>
  <div class="form-group">
    <%= f.submit "Modifier l´article", class: 'btn btn-primary' %>
  </div>
<% end %>
于 2022-02-07T20:16:21.563 回答