Ruby Rails Activerecord - ID 在模型中交换
Ruby on Rails Activerecord - ids are Exchanged in Model
我在 Rails 4.2.0 和 Ruby 2.1.0 中使用 Ruby,并且我有一个自加入协会。这是我的迁移:
class CreateStateTemplates < ActiveRecord::Migration
def change
create_table :state_templates do |t|
t.string :name
t.references :next
t.references :prev
t.timestamps null: false
end
end
end
这是我的模型:
class StateTemplate < ActiveRecord::Base
has_one :prev, :class_name => "StateTemplate", :foreign_key => "prev_id"
belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "prev_id"
has_one :next, :class_name => "StateTemplate", :foreign_key => "next_id"
belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "next_id"
end
这里我填一些状态:
StateTemplate.find(1).update(:next => StateTemplate.find(2))
StateTemplate.find(2).update(:next => StateTemplate.find(3), :prev => StateTemplate.find(1))
StateTemplate.find(3).update(:next => StateTemplate.find(4), :prev => StateTemplate.find(2))
StateTemplate.find(4).update(:next => StateTemplate.find(5), :prev => StateTemplate.find(3))
StateTemplate.find(5).update(:prev => StateTemplate.find(4))
但是奇怪的事情发生了。当我从 StateTemplate 中取出一条记录并将其放在 concole 上时,我得到了这个:
2.1.0 :007 > StateTemplate.find(2)
StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]]
=> #<StateTemplate id: 2, name: "two", next_id: 1, prev_id: 3, created_at: "2017-07-22 11:51:30", updated_at: "2017-07-22 11:51:30">
这不对,因为 next_id
必须是 3,但是当我提到下一个状态时,我得到了这个:
2.1.0 :008 > StateTemplate.find(2).next
StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]]
StateTemplate Load (0.0ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."next_id" = ? LIMIT 1 [["next_id", 2]]
=> #<StateTemplate id: 3, name: "three", next_id: 2, prev_id: 4, created_at: "2017-07-22 11:51:30", updated_at: "2017-07-22 11:51:30">
这是对的。这是我的问题:为什么交换了记录中的 ID,但引用了正确的记录?
两个 belongs_to
协会具有相同的名称 (:state_template
),但它们不需要具有不同的名称。此外,我认为 prev
和 next
指向 self
而不是指向链接模板有点令人困惑。
我会这样改变关联:
belongs_to :next, class_name: 'StateTemplate'
belongs_to :prev, class_name: 'StateTemplate'
has_one :predecessor, foreign_key: 'next_id', class_name: 'StateTemplate'
has_one :successor, foreign_key: 'prev_id', class_name: 'StateTemplate'
这甚至可以简化。因为如果模板有 belongs_to :next
,那么反向 has_one
会自动成为 prev
。因此从该模型中删除 prev_id
并仅使用以下内容:
belongs_to :next, class_name: 'StateTemplate'
has_one :prev, foreign_key: 'next_id', class_name: 'StateTemplate'
我在 Rails 4.2.0 和 Ruby 2.1.0 中使用 Ruby,并且我有一个自加入协会。这是我的迁移:
class CreateStateTemplates < ActiveRecord::Migration
def change
create_table :state_templates do |t|
t.string :name
t.references :next
t.references :prev
t.timestamps null: false
end
end
end
这是我的模型:
class StateTemplate < ActiveRecord::Base
has_one :prev, :class_name => "StateTemplate", :foreign_key => "prev_id"
belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "prev_id"
has_one :next, :class_name => "StateTemplate", :foreign_key => "next_id"
belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "next_id"
end
这里我填一些状态:
StateTemplate.find(1).update(:next => StateTemplate.find(2))
StateTemplate.find(2).update(:next => StateTemplate.find(3), :prev => StateTemplate.find(1))
StateTemplate.find(3).update(:next => StateTemplate.find(4), :prev => StateTemplate.find(2))
StateTemplate.find(4).update(:next => StateTemplate.find(5), :prev => StateTemplate.find(3))
StateTemplate.find(5).update(:prev => StateTemplate.find(4))
但是奇怪的事情发生了。当我从 StateTemplate 中取出一条记录并将其放在 concole 上时,我得到了这个:
2.1.0 :007 > StateTemplate.find(2)
StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]]
=> #<StateTemplate id: 2, name: "two", next_id: 1, prev_id: 3, created_at: "2017-07-22 11:51:30", updated_at: "2017-07-22 11:51:30">
这不对,因为 next_id
必须是 3,但是当我提到下一个状态时,我得到了这个:
2.1.0 :008 > StateTemplate.find(2).next
StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]]
StateTemplate Load (0.0ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."next_id" = ? LIMIT 1 [["next_id", 2]]
=> #<StateTemplate id: 3, name: "three", next_id: 2, prev_id: 4, created_at: "2017-07-22 11:51:30", updated_at: "2017-07-22 11:51:30">
这是对的。这是我的问题:为什么交换了记录中的 ID,但引用了正确的记录?
两个 belongs_to
协会具有相同的名称 (:state_template
),但它们不需要具有不同的名称。此外,我认为 prev
和 next
指向 self
而不是指向链接模板有点令人困惑。
我会这样改变关联:
belongs_to :next, class_name: 'StateTemplate'
belongs_to :prev, class_name: 'StateTemplate'
has_one :predecessor, foreign_key: 'next_id', class_name: 'StateTemplate'
has_one :successor, foreign_key: 'prev_id', class_name: 'StateTemplate'
这甚至可以简化。因为如果模板有 belongs_to :next
,那么反向 has_one
会自动成为 prev
。因此从该模型中删除 prev_id
并仅使用以下内容:
belongs_to :next, class_name: 'StateTemplate'
has_one :prev, foreign_key: 'next_id', class_name: 'StateTemplate'