Rails 3:验证关联并向用户完美展示验证结果

Ail*_*lho 5 validation ruby-on-rails ruby-on-rails-3

首先,我正在使用 Rails 3.0.9 和 ruby​​ 1.8.7。\n我需要一些帮助,因为我无法验证并在屏幕上向用户完美显示它。

\n\n

该模型:

\n\n
class Book < ActiveRecord::Base\n    belongs_to :genre\n    validates_presence_of :title, :genre\n    attr_accessible :genre_id\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

表格:

\n\n
<div class="field">\n    <%= f.label :genre %><br />\n    <%= f.collection_select(:genre_id, Genre.all(:order => :name), :id, :name, :prompt => \'Select\') %>\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我发送空白表单(默认选择提示值)时,错误消息完美地显示“流派不能为空”,但在表单中我收到如下 html:

\n\n
<div class="field">\n    <div class="field_with_errors">\n        <label for="book_genre">Genre</label>\n    </div>\n    <br>\n    <select name="book[genre_id]" id="book_genre_id">\n        <option value="">Select</option>\n        <option value="2">Gramatic</option>\n        <option value="1">Terror</option>\n    </select>\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我也需要 div.field_with_erros 内的选择字段,因为我在 CSS 中定义了红色背景。

\n\n

之后我尝试将 f.collection_select :genre_id 更改为 :genre

\n\n

现在我在 div.field_with_erros 中得到了选择字段。Owwww Yeahhh 胜利了,一会儿,直到我意识到验证总是指责错误,rails 不知道选择字段 :genre 是它寻找的 :genre_id 。

\n\n

我的问题是:如何在验证中将 :genre 更改为 :genre_id ?或者大家有更好的方法吗?

\n\n

继续进行测试,我尝试将标签和collection_select更改为genre_id,验证工作完美,但没有使用div.field_with_errors生成html,所以我尝试将:genre_id放入validates_presence_of,所以现在它看起来像:“validates_presence_of:title ,:流派,:流派_id”。

\n\n

太好了,但是……

\n\n
    \n
  1. 当我提交表单并选择默认提示值时,验证工作正常,但他们指责 2 个错误,一个错误为 :genre,另一个错误为:genre_id (\xc2\xac\xc2\xac),但 html 很好, label 和 select 位于 div.field_with_erros 内。

  2. \n
  3. 如果我提交表单并从类型中选择一些值,\n 验证和 html 就可以了。

  4. \n
  5. 如果我提交表单,但我已将某些选项的值更改为无效,\n测试模型之间的验证是否有效,验证确实\n工作正常,但 html 未创建 div.field_with_erros。

  6. \n
\n\n

有人可以帮助我吗?\n(是的,我的英语不是最好的。抱歉!)

\n

Chr*_*wis 1

我创建了一些脚手架模型来测试这一点。我设置了 2 个迁移:

class CreateGenres < ActiveRecord::Migration
  def change
    create_table :genres do |t|
      t.string :title
      t.timestamps
    end
  end
end

class CreateBooks < ActiveRecord::Migration
  def change
    create_table :books do |t|
      t.string :name
      t.references :genre
      t.timestamps
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

以我的形式:

<%= f.label :genre_id %>
<%= f.collection_select(:genre_id, Genre.all(:order => :title), :id, :title, :prompt => 'Select') %>
Run Code Online (Sandbox Code Playgroud)

在我的模型中:

class Genre < ActiveRecord::Base
  attr_accessible :title
  has_many :books
end

class Book < ActiveRecord::Base
  belongs_to :genre
  validates_presence_of :name, :genre_id
  attr_accessible :name, :genre_id
end
Run Code Online (Sandbox Code Playgroud)

验证然后按照我的预期进行......