相关对象未保存

时间:2014-06-25 00:02:37

标签: ruby-on-rails activerecord model-associations

我有模特:

class Idea < ActiveRecord::Base
  has_many :connections, :class_name => 'IdeaConnection', :foreign_key => 'idea_a_id', :dependent => :destroy
  has_many :ideas, :through => :connections, :source => :idea_b, :dependent => :destroy
end

class IdeaConnection < ActiveRecord::Base
  belongs_to :idea
  belongs_to :idea_a, :class_name => 'Idea'
  belongs_to :idea_b, :class_name => 'Idea'
  belongs_to :relationship
end

class Relationship < ActiveRecord::Base
  has_many :idea_connections 
end

您可以看到,Idea通过Connections(连接表)拥有自己。每个Connection条目都属于Relationship。我想要做的是,在向另一个人添加一个想法之后:

Idea.find(1).ideas << Idea.find(2)

正常工作并保存,在连接表上获取连接并更新其关系:

例如:

Idea.find(1).connections.find_by_idea_b_id(Idea.f
ind(2).id).relationship = Relationship.find(1)

它处理正确,但不会保存。

请帮忙,我错过了什么?

ps:我不想通过手动编辑relationship_id来实现它,因为它很难看。 ps2:在回答之前,请记住autosave:true对belongs_to / has_many关系不起作用的事实。

3 个答案:

答案 0 :(得分:1)

您正在使用连接对象。记住它。 您的问题是您在find_by...关联中调用has_many方法。它返回一条记录但是Idea模型没有ruby属性链接。见here为什么。这就是Idea#save无法调用IdeaConnection#save的原因(请记住,对于级联保存connections,必须具有自动保存功能:如果连接已存在,则为true。

所以我建议你两个选择:

  1. :inverse_ofIdea#connections关系上设置IdeaConnection#idea_a并在使用Idea.find(1).connections.find_by_idea_b_id(Idea.f ind(2).id).relationship = Relationship.find(1)进行修改之前预加载所有记录。但我不建议你这样做,因为:
  2. 正如我所说,你正在使用连接对象。就这样做:

    Idea.find(1).connections.create do |connection|
      connection.idea_b = Idea.find(2)
      connection.relationship = Relationship.first
    end
    

答案 1 :(得分:0)

这行代码不会保存它

Idea.find(1).connections.first.relationship = Relationship.first   

您需要做的是:

方法#1 :(添加与has_many关系的连接)

Relationship.first.idea_connections << Idea.find(1).connections.first

OR

方法#2 :(将relationship_id添加到连接然后手动保存)

connection = Idea.find(1).connections.first
connection.relationship_id = Relationship.first.id
connection.save

答案 2 :(得分:0)

关系对象级别的分配不会/不会自动保存;你必须告诉他们。在ActiveRecord中,push方法(&lt;&lt;)已经内置了它,这就是为什但是设置值(=)没有内置的保存,因此您必须手动执行此操作。

如果您有兴趣,可以在此处找到另一个SO问题的链接,其中的答案说明了推送保存的原因:Rails push into array saves object