使用Rails 4和Ruby 2.1。
假设我有两个模型,团队和玩家。它们看起来像这样:
team.rb:
# == Schema Information
#
# Table name: teams
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime
# updated_at :datetime
#
class Team < ActiveRecord::Base
has_many :players
accepts_nested_attributes_for :players
end
player.rb:
# == Schema Information
#
# Table name: players
#
# id :integer not null, primary key
# name :string(255)
# team_id :integer
# created_at :datetime
# updated_at :datetime
#
class Player < ActiveRecord::Base
belongs_to :team
end
超级简单。我可以毫无困难地做到以下几点:
> params = { team: {
> name: "Foo", players_attributes: [
> {name: "Bar"}
> ]
> }}
> team = Team.new(params[:team]) # => #<Team id: nil, name: "Foo", created_at: nil, updated_at: nil>
> team.save # => true
> team.players.first.name # => "Bar"
好。现在假设我更新了Player模型,以便在没有属于团队的情况下创建一个Player:
player.rb:
# == Schema Information
#
# Table name: players
#
# id :integer not null, primary key
# name :string(255)
# team_id :integer
# created_at :datetime
# updated_at :datetime
#
class Player < ActiveRecord::Base
belongs_to :team
validates_presence_of :team
end
现在,当我尝试同样的事情时:
> params = { team: {
> name: "Foo", players_attributes: [
> {name: "Bar"}
> ]
> }}
> team = Team.new(params[:team]) # => #<Team id: nil, name: "Foo", created_at: nil, updated_at: nil>
> team.save # => false
> team.errors # => #<ActiveModel::Errors:0x00000002bd13f0 @base=#<Team id: nil, name: "Foo", created_at: nil, updated_at: nil>, @messages={:"players.team"=>["can't be blank"]}>
如果没有玩家要求的团队,team_id显然是使用嵌套属性设置的。但是,一旦我需要它,验证在它有机会被设置之前就会破灭。我做错了吗?
答案 0 :(得分:5)
替换
class Team < ActiveRecord::Base
has_many :players
accepts_nested_attributes_for :players
end
class Player < ActiveRecord::Base
belongs_to :team
validates_presence_of :team
end
使用
class Team < ActiveRecord::Base
has_many :players, inverse_of: :team
accepts_nested_attributes_for :players
end
class Player < ActiveRecord::Base
belongs_to :team, inverse_of: :players
validates_presence_of :team
end
在关联中添加inverse_of
选项。