我正在使用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'} %>
答案 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