代码之家  ›  专栏  ›  技术社区  ›  Shuo

保存活动记录时,关联对象的保存顺序是什么?

  •  8
  • Shuo  · 技术社区  · 16 年前

    在rails中,保存活动的_记录对象时,其关联对象也将被保存。但是有一个和多个关联在保存对象时有不同的顺序。

    我有三个简化模型:

    class Team < ActiveRecord::Base
      has_many :players
      has_one :coach
    end
    
    class Player < ActiveRecord::Base
      belongs_to :team
      validates_presence_of :team_id
    end
    
    class Coach < ActiveRecord::Base
      belongs_to :team
      validates_presence_of :team_id
    end
    

    我以为 team.save 被称为,团队应该在其相关教练和球员之前获救。

    我使用以下代码来测试这些模型:

    t = Team.new
    team.coach = Coach.new
    team.save!
    

    team.save! 返回true。

    但在另一项测试中:

    t = Team.new
    team.players << Player.new
    team.save!
    

    团队拯救 给出以下错误:

    > ActiveRecord::RecordInvalid:
    > Validation failed: Players is invalid
    

    我知道了 团队拯救 按以下顺序保存对象:1)玩家、2)团队和3)教练。这就是我出错的原因:当一名球员被解救时,球队还没有id,所以 validates_presence_of :team_id 在玩家中失败。

    有人能给我解释一下为什么物体是按这个顺序保存的吗?我觉得这似乎不合逻辑。

    2 回复  |  直到 16 年前
        1
  •  0
  •   Salil    16 年前

    你应该使用“validates_associated”来完成这一点

    检查 Here

    比如说不兑现支票

    class Team < ActiveRecord::Base
      has_many :players
      has_one :coach
      validates_associated :players, :coach  ###MOST IMPORTANT LINE 
    end
    
    class Player < ActiveRecord::Base
      belongs_to :team
      validates_presence_of :team_id
    end
    
    class Coach < ActiveRecord::Base
      belongs_to :team
      validates_presence_of :team_id
    end
    

    在你的控制器里

    t = Team.new
    
    @coach = t.build_coach(:column1=> "value1", :column2=> "value2" )  # This create new object with @coach.team_id= t.id
    @players = t.players.build
    
    t.save#This will be true it passes the validation for all i.e. Team, COach & Player also save all at once otherwise none of them will get saved.
    
        2
  •  -1
  •   sockmonk    13 年前

    让我们看看你的失败测试:

    t = Team.new
    team.players << Player.new
    team.save!
    

    为球队增加一名新球员。球员协会试图在2号线上设置球员的球队id。这就是<&书信电报;接线员在工作。当你保存团队时,它不会被更新,所以即使团队先被保存,玩家仍然有一个空的团队id。在这种情况下,你可以通过交换第2行和第3行来轻松解决它。