是否可以在Rails中验证grouped_collection_select?

时间:2018-07-27 04:02:15

标签: ruby-on-rails ruby validation model-view-controller activerecord

我正在使用Rails应用程序,用户可以在其中发布有关不同艺术形式(例如音乐,绘画,摄影等)的报价。必须为每个Quote分配一个Medium(例如音乐或摄影)和一个Genre(例如音乐的Jazz或Rock and Roll或摄影的Landscape)。

我在“报价”表单的“类型”字段中使用了grouped_collection_select,这对分类类型非常有用,但是我想防止任何人选择不属于媒体的类型他们已经选择了。

我知道我可以像this Railscast中那样使用javascript动态地做到这一点,但是我想创建一个验证以确保没有不良数据进入数据库。

是否有一种方法可以在我的Quote模型中对此进行验证,从而无法用一种没有正确媒介的流派保存Quote?例如,这将阻止某人保存诸如“摄影”和“爵士”流派的内容。

这是我的模特:

class Quote < ApplicationRecord
  belongs_to :medium
  belongs_to :genre
end

class Medium < ApplicationRecord
  has_many :quotes
  has_many :genres
end

class Genre < ApplicationRecord
  has_many   :quotes
  belongs_to :medium
end

这是我的报价单上的字段:

<%= f.label :medium, 'Medium' %>
<%= f.collection_select :medium_id, Medium.order(:name), :id, :name, {prompt: 'Select a medium'}, {class: 'form-control'} %>

<%= f.label :genre, 'Genre' %>
<%= f.grouped_collection_select :genre_id, Medium.order(:name), :genres, :name, :id, :name, {prompt: 'Select a genre'}, {class: 'form-control'} %>

2 个答案:

答案 0 :(得分:1)

您可以使用rails validate方法来实现此目的,

validate: check_medium
def check_medium
  errors.add(:base, "Your error message") if genre.try(:medium) != medium
end

答案 1 :(得分:1)

我的建议是只对genre_id表中的quotes进行故事。 belongs_to :medium是不必要的,因为每种类型都已经知道其媒介。使用这样的架构,您完全不必担心中等类型的不匹配。型号:

class Quote
  belongs_to :genre

  # With delegation you still can do something like quote.medium
  delegate :medium, to: :genre
end

class Medium
  has_many :genres
  has_many :quotes, through: :genres
end

class Genre
  belongs_to :medium
  has_many :quotes
end