如何添加关系,使相关对象出现在ActiveRecord CollectionProxy中的某个位置?
How to add a relationship so that related object would appear in a certain position in ActiveRecord CollectionProxy?
情况:
我有 4 个模型具有如下关系:
class A < ActiveRecord::Base
belongs_to :b
belongs_to :c
belongs_to :d
end
class B < ActiveRecord::Base
has_many :as, dependent: :destroy
end
class C < ActiveRecord::Base
belongs_to :d
end
class D < ActiveRecord::Base
has_many :cs, dependent: :destroy
end
问题:
我需要将模型 A 对象 a
与模型 B 对象相关联 b
但我还需要为对象 a
设置一个位置 ActiveRecord CollectionProxy调用 b.as
时不起作用。 所有将对象 a
添加到 a.bs
中特定位置的尝试最终都会在末尾 新添加 a
。有可能吗?我知道有可能在数组中和查询时定义排序,但是在添加新关系时是否可以直接定义排序?
示例:
模型 B 对象 b
有 3 个模型 A 对象。
b.as
=> #<ActiveRecord::Associations::CollectionProxy [
#<A id: 39038, quantity: 3.0 created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4144, c_id: nil, b_id: 81218>,
#<A id: 39039, quantity: 2.0, created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4145, c_id: nil, b_id: 81218>,
#<A id: 39040, quantity: 2.0, created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4145, c_id: 1590, b_id: 81218>]>
我创建了第四个模型 A 对象 a
,我需要它在调用 b.as
时出现在第二位,如下所示:
a = A.create(quantity: 4.0, d: D.find(4144), c: C.find(1612), b: b)
基本上顺序应该这样定义:
b.as
=>
a1: d_id: 4144, c_id: nil
a2: d_id: 4144, c_id: 1612
a3: d_id: 4145, c_id: nil
a4: d_id: 4145, c_id: 1590
...意味着每个具有相同 d_id
属性的 a
对象应该被组合在一起,同时将具有 c_id.nil?
的那些 a
放在首位。
add 方法总是将它添加到列表的末尾。您需要某种位置属性来实现您想要的。如果你不想自己实现,你可以看看 Acts as list gem。另一种选择是在 As 模型上添加 default_scope { order: :key_to_order_by }
。
has_many :as, -> { order(d_id: :asc, c_id: :asc) }
应该很接近,除了 nil 排在最高 cd_id
之后。那是 postgres 做的排序,所以我不知道你是否可以在那里做很多事情。
情况:
我有 4 个模型具有如下关系:
class A < ActiveRecord::Base
belongs_to :b
belongs_to :c
belongs_to :d
end
class B < ActiveRecord::Base
has_many :as, dependent: :destroy
end
class C < ActiveRecord::Base
belongs_to :d
end
class D < ActiveRecord::Base
has_many :cs, dependent: :destroy
end
问题:
我需要将模型 A 对象 a
与模型 B 对象相关联 b
但我还需要为对象 a
设置一个位置 ActiveRecord CollectionProxy调用 b.as
时不起作用。 所有将对象 a
添加到 a.bs
中特定位置的尝试最终都会在末尾 新添加 a
。有可能吗?我知道有可能在数组中和查询时定义排序,但是在添加新关系时是否可以直接定义排序?
示例:
模型 B 对象 b
有 3 个模型 A 对象。
b.as
=> #<ActiveRecord::Associations::CollectionProxy [
#<A id: 39038, quantity: 3.0 created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4144, c_id: nil, b_id: 81218>,
#<A id: 39039, quantity: 2.0, created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4145, c_id: nil, b_id: 81218>,
#<A id: 39040, quantity: 2.0, created_at: "2016-02-01 15:51:26", updated_at: "2016-02-01 15:51:26", d_id: 4145, c_id: 1590, b_id: 81218>]>
我创建了第四个模型 A 对象 a
,我需要它在调用 b.as
时出现在第二位,如下所示:
a = A.create(quantity: 4.0, d: D.find(4144), c: C.find(1612), b: b)
基本上顺序应该这样定义:
b.as
=>
a1: d_id: 4144, c_id: nil
a2: d_id: 4144, c_id: 1612
a3: d_id: 4145, c_id: nil
a4: d_id: 4145, c_id: 1590
...意味着每个具有相同 d_id
属性的 a
对象应该被组合在一起,同时将具有 c_id.nil?
的那些 a
放在首位。
add 方法总是将它添加到列表的末尾。您需要某种位置属性来实现您想要的。如果你不想自己实现,你可以看看 Acts as list gem。另一种选择是在 As 模型上添加 default_scope { order: :key_to_order_by }
。
has_many :as, -> { order(d_id: :asc, c_id: :asc) }
应该很接近,除了 nil 排在最高 cd_id
之后。那是 postgres 做的排序,所以我不知道你是否可以在那里做很多事情。