Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何将现有记录添加到has_many中,而不立即将其保存到数据库中?_Ruby On Rails_Ruby On Rails 3 - Fatal编程技术网

Ruby on rails 如何将现有记录添加到has_many中,而不立即将其保存到数据库中?

Ruby on rails 如何将现有记录添加到has_many中,而不立即将其保存到数据库中?,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,假设我有这个: class Pirate < ActiveRecord::Base has_many :parrots validates_presence_of :name end class Parrot < ActiveRecord::Base belongs_to :pirate end 因为海盗对象无效(它缺少一个名称),我不想保存它。然而,这些鹦鹉现在与海盗有联系,并在数据库中提交 如何分配鹦鹉,但仅当p.save成功时才将指向鹦鹉的链接保存到数据库?例如

假设我有这个:

class Pirate < ActiveRecord::Base
  has_many :parrots
  validates_presence_of :name
end

class Parrot < ActiveRecord::Base
  belongs_to :pirate
end
因为海盗对象无效(它缺少一个名称),我不想保存它。然而,这些鹦鹉现在与海盗有联系,并在数据库中提交


如何分配鹦鹉,但仅当p.save成功时才将指向鹦鹉的链接保存到数据库?例如,如何在一次交易中保存海盗和指向鹦鹉的链接?

您可以重新安排您的操作:

p = Pirate.first
p.name = nil
if p.save
  p.parrot_ids = [1,2,3]
end
注意,在p.save之后不需要“if p.valid?”;因为有效吗?由save调用,确定是否尝试将数据写入数据库

如果您的鹦鹉不是预先存在的,您可以使用p.parrots.build(attributes={…})创建新的鹦鹉,这些鹦鹉在保存盗版父对象之前不会被保存


请参阅中有关未保存对象和关联的部分。

您可能应该查看活动记录事务。 您可以将代码包装为事务块中的代码。事务是保护块,SQL语句只有在它们都可以作为一个原子操作成功时才是永久的


不幸的是,Rails是以这种方式为现有对象构建的;如果对象已经存在,并且您使用其关联进行futz,则始终会触发更新。如果您能够像KenB提到的那样使用
.build
选项,那么这就是解决问题的一种方法。然而,除此之外,我目前只能想到一种方法来处理这个问题;将整个操作包装到事务中,如下所示:

Pirate.transaction do
    p = Pirate.first
    p.name = nil
    p.parrot_ids = [1,2,3]

    if !p.save # Performing save in this manner will return false if validations fail (ie same as your p.valid?)
        raise ActiveRecord::Rollback # should rollback anything executing within this transaction block
    end
end

如果这有帮助,请告诉我,如果没有帮助,请道歉。

嗨,肯,我希望鹦鹉们参与验证。我有一个关于:鹦鹉ID的集体作业。如果验证失败是因为用户试图入侵一只他们不允许链接的鹦鹉,那么p.save应该失败,之后p.parrots应该返回用户尝试的鹦鹉。出于某种原因,我刚刚注意到这个问题已经超过两年了。很抱歉提出了亡灵术的问题(假设它不再相关)。
Pirate.transaction do
    p = Pirate.first
    p.name = nil
    p.parrot_ids = [1,2,3]

    if !p.save # Performing save in this manner will return false if validations fail (ie same as your p.valid?)
        raise ActiveRecord::Rollback # should rollback anything executing within this transaction block
    end
end