Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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 3 ruby-on-rails在模型持久性方面的不一致性通过关联产生了很多问题_Ruby On Rails 3_Has Many Through - Fatal编程技术网

Ruby on rails 3 ruby-on-rails在模型持久性方面的不一致性通过关联产生了很多问题

Ruby on rails 3 ruby-on-rails在模型持久性方面的不一致性通过关联产生了很多问题,ruby-on-rails-3,has-many-through,Ruby On Rails 3,Has Many Through,我试图弄清楚当我通过关联创建一个has\u many时发生了什么 型号: class Foo has_many :bars has_many :bazes, through: :bars acceptes_nested_attributes_for :bars acceptes_nested_attributes_for :bazes end class Bar belongs_to :foo belongs_to :baz before_create :upd

我试图弄清楚当我通过关联创建一个has\u many时发生了什么

型号:

class Foo
  has_many :bars
  has_many :bazes, through: :bars

  acceptes_nested_attributes_for :bars
  acceptes_nested_attributes_for :bazes
end

class Bar
  belongs_to :foo
  belongs_to :baz

  before_create :update_some_attr

  def update_some_attr
    if self.baz.new_record?
      raise "baz is new record"
    else
      raise "baz is not new record"
    end
  end
end

class Baz
  has_many :bars
end
表格:

如果我在
update_some_attr
中出现错误并检查类,
self.baz.new_record?
返回
true
;然而ELSE条件触发,这意味着Baz模型在创建Bar记录之前已经被持久化了。我只是想弄明白为什么调试时会出现这种不一致


首先,我无法直接回答为什么控制台输出和条件语句都会产生不一致的行为。然而,我确实看到了重写方法的机会,因此.new_记录?这种情况可以避免:

您正在应用before_create回调,这意味着只有在Model.create()上才会触发回调,那么在这种情况下,为什么要限定实例是否为新实例?如果应该在现有记录上使用该方法来更新某个属性,我将坚持使用update_attributes()方法。另一种方法是始终需要现有记录,并将回调更改为“创建后”。这将更有意义,因为您的方法称为“更新”

after_create :update_some_attr

def update_some_attr(*args={attribute: :name, value: "John Doe"})
  args.assert_valid_keys(:attribute, :value)
  attribute, value = [args[:attribute], args[:value]]

  self.update_attributes(attribute => value)
end

我想你可能会期待这样的事情发生:

Bar属于Foo和Baz,因此在创建Bar之前,ActiveRecord必须创建Foo和Baz,获取id并将其设置在关联id(Foo和Baz)上

但我相信这些协会给你带来了麻烦:

由于Foo有许多条和Baz,ActiveRecord将在创建Foo之前尝试保存这些关联,这可能就是为什么Baz已经在您的方法上持久化的原因

一种解决方案(如果是这样的话)是将Bar和Baz之间的关联更改为:

class Bar
  has_many :bazs
end
class Baz
  belongs_to :bar
end
class Foo
  has_many :bars

  acceptes_nested_attributes_for :bars
end

class Bar
  belongs_to :foo
  belongs_to :baz

  acceptes_nested_attributes_for :baz      

  before_create :update_some_attr

  def update_some_attr
    if self.baz.new_record?
      raise "baz is new record"
    else
      raise "baz is not new record"
    end
  end
end

class Baz
  has_many :bars
end
但正如我刚才意识到的,您需要Baz有许多条,因此您可以尝试删除Foo和accepts_嵌套的_属性上的关联

has_many :basz, through: :bars
acceptes_nested_attributes_for :bazes
并接受条形图模型上的嵌套属性:

acceptes_nested_attributes_for :baz
你会遇到这样的情况:

class Bar
  has_many :bazs
end
class Baz
  belongs_to :bar
end
class Foo
  has_many :bars

  acceptes_nested_attributes_for :bars
end

class Bar
  belongs_to :foo
  belongs_to :baz

  acceptes_nested_attributes_for :baz      

  before_create :update_some_attr

  def update_some_attr
    if self.baz.new_record?
      raise "baz is new record"
    else
      raise "baz is not new record"
    end
  end
end

class Baz
  has_many :bars
end

您是否缺少Baz模型中的
has_many:foos,through::bar