Ruby-on-Rails:验证子对象的唯一性(或数量)
我有一个模型,Game
,它has_many :piles
。事实上,我知道每个游戏都有 4 个堆,每个堆都有不同的(在游戏范围内)内容
。我用于创建游戏的网络表单允许用户选择四个内容(如 c_type_#)。因此,我能够在创建游戏时填充桩。然而,我不知道如何确保我拥有恰好 4 个独特的桩。我的模型看起来像这样:
class Game < ActiveRecord::Base
has_many :piles
def after_create
1.upto(4) do |num|
piles.create("contents" => "c_type_#{num}")
end
end
end
class Pile < ActiveRecord::Base
belongs_to :game
validates_uniqueness_of :contents, :scope => "game_id"
end
... 我的迁移添加桩看起来像:
class CreatePiles < ActiveRecord::Migration
def self.up
create_table :piles do |t|
t.integer :game_id
t.string :contents
end
add_index :piles, [:game_id, :contents], :unique => true
end
def self.down
drop_table :piles
end
end
...但这意味着非唯一的桩不会默默地添加到数据库中;父游戏最终的堆数少于 4 堆。
我目前已经通过 Game validate :unique_pile_contents, :on =>; 解决了这个问题:create
,其中 unique_pile_contents
验证 c_type_# 值的 uniq'd 数组的长度是否为 4 - 但这感觉非常混乱。有更好的办法吗?
I have a model, Game
, which has_many :piles
. In fact, I know that each Game has exactly 4 piles, each of which has a different (at the scope of the Game) contents
. My web-form for creating a Game allows the user to pick the four contents (as c_type_#). I'm therefore able to populate the Piles at creation of the Game. However, I can't figure out how to ensure that I have precisely 4 unique Piles. My models look like this:
class Game < ActiveRecord::Base
has_many :piles
def after_create
1.upto(4) do |num|
piles.create("contents" => "c_type_#{num}")
end
end
end
class Pile < ActiveRecord::Base
belongs_to :game
validates_uniqueness_of :contents, :scope => "game_id"
end
... and my migration to add Piles looks like:
class CreatePiles < ActiveRecord::Migration
def self.up
create_table :piles do |t|
t.integer :game_id
t.string :contents
end
add_index :piles, [:game_id, :contents], :unique => true
end
def self.down
drop_table :piles
end
end
...but all this means is that the non-unique Piles aren't added to the database, silently; and the parent Game ends up with fewer than 4 piles.
I have currently worked around this by having Game validate :unique_pile_contents, :on => :create
, where unique_pile_contents
verifies that the length of a uniq'd array of the c_type_# values is 4 - but this feels very kludgy. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经成功解决了这个问题,作为我正在解决的另一个问题的一部分。请参阅从父级表单创建一定数量的子对象获取答案(以及问题中稍微简单的示例) )。
I've managed to solve this as part of another problem I was tackling. See Creating a set number of child objects from a parent's form for the answer (and a slightly simpler example in the question).