代码之家  ›  专栏  ›  技术社区  ›  Lee McAlilly

是否可以在Rails中验证分组的集合?

  •  0
  • Lee McAlilly  · 技术社区  · 6 年前

    我正在开发一个Rails应用程序,用户可以在其中发布关于不同艺术形式(如音乐、绘画、摄影等)的报价。每个 Quote 必须分配一个 Medium (如音乐或摄影)和 Genre (如爵士乐、摇滚乐、风景摄影)。

    我用的是 grouped_collection_select 对于我的引用表单上的体裁字段,这对分类体裁非常有效,但是我想阻止任何人选择不属于他们选择的媒体的体裁。

    我知道我可以用javascript动态地完成这项工作,如 this Railscast ,但我想创建一个验证以确保没有坏数据进入数据库。

    有没有办法在我的 引用 做模特,这样就不可能 引用 可以用没有正确媒体的流派保存吗?这将阻止人们保存一些媒介“摄影”和类型“爵士乐”,例如。

    以下是我的模特:

    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 回复  |  直到 6 年前
        1
  •  1
  •   Kshitij    6 年前

    你可以用铁轨 validate 实现这一目标的方法,

    validate: check_medium
    def check_medium
      errors.add(:base, "Your error message") if genre.try(:medium) != medium
    end
    
        2
  •  1
  •   ahawrylak    6 年前

    我在这里的建议只讲故事 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