[英]Add Relation / Association model value to Base model
I have two objects, A
and B
. 我有两个对象A
和B
Each have many of the other, using relationshipA
. 每一个都有许多其他relationshipA
,使用的是relationshipA
。 relationshipA
has a property propertyA
. relationshipA
具有属性propertyA
。 Can I merge the properties of relationshipA
and either A
or B
when I perform a fetch? 执行提取时是否可以合并relationshipA
的属性以及A
或B
?
For example 例如
A.find(params[:id]).relationshipAs
I'd like that to return me Bs
, but also append the properties from relationshipA
into them, at least when rendering the json. 我想让我返回Bs
,但至少在渲染json时,还要将relationshipA
的属性附加到它们中。
class A < ActiveRecord::Base
has_many :relationship_a
has_many :b, through: :relationship_a
end
class B < ActiveRecord::Base
has_many :relationship_a
has_many :a, through: :relationship_a
end
class RelationshipA < ActiveRecord::Base
belongs_to :A
belongs_to :B
end
Assuming B has properties prop1
, prop2
and prop3
and RelationshipA
has prop4
, I'd like to get a json response from: 假设B有性质prop1
, prop2
和prop3
和RelationshipA
有prop4
,我希望得到一个JSON响应:
render json: A.find(params[:id]).bs
I'd like to expect: 我希望:
[{
'prop1' : 'value',
'prop2' : 'value',
'prop3' : 'value',
'prop4' : 'value'
}, ...]
Here's a console example: 这是一个控制台示例:
a1 = A.create
b1 = B.create
b2 = B.create
a1.bs = [b1, b2]
RelationshipA.where(a_id: a1.id).first.prop4 = 'Hello'
RelationshipA.where(a_id: a1.id).last.prop4 = 'There'
*now output all of a1's bs including the relationships' prop4 value*
#<ActiveRecord::Associations::CollectionProxy [#<B id: 1, prop1: nil, prop2: nil, prop3: nil, created_at: "2014-07-09 20:37:12", updated_at: "2014-07-09 20:37:12", prop4: 'Hello'>, #<B id: 2, prop1: nil, prop2: nil, prop3: nil, created_at: "2014-07-09 20:37:12", updated_at: "2014-07-09 20:37:12", prop4: 'There'>]>
I see 2 questions: 我看到两个问题:
Defining a custom json method: 定义自定义json方法:
class A < ActiveRecord::Base
has_many :relationships, :inverse_of :a
has_many :bs, :through => :relationships
end
class B < ActiveRecord::Base
# prop1
has_many :relationships, :inverse_of :b
has_many :as, :through => :relationships
end
class Relationship < ActiveRecord::Base
# prop4
belongs_to :a, inverse_of: :relationships
belongs_to :b, inverse_of: :relationships
def as_json(options: {})
{
prop1: b.prop1,
prop4: prop4
}
end
end
relationships = A.includes(relationships: :b).find(params[:id]).relationships
puts relationships.to_json
The question is very abstract. 这个问题非常抽象。 If you can stick with Relationship
objects, then that is probably your best bet. 如果您可以坚持使用Relationship
对象,那可能是最好的选择。 Using includes
will give you a single or 2 queries. 使用includes
将给您一个或两个查询。
If you need to have a B
with the knowledge of how you brought back B
, then you probably want to add attr_accessor :prop4
to B
and an "extension" block to Relationship
's has_many
clause to set B's :prop4
. 如果你需要有B
与你怎么带回来的知识B
,那么你可能要添加attr_accessor :prop4
到B
和“扩展”块Relationship
的has_many
条款设置B的:prop4
。
It seems the best that I can do is a hash of the values, but not through the initial query or any built in functions. 看来,我能做的最好的事情是值的散列,而不是通过初始查询或任何内置函数。 @kbrock has a solid answer, but I prefer the attributes
approach. @kbrock有一个可靠的答案,但我更喜欢使用attributes
方法。
class A < ActiveRecord::Base
has_many :relationships, :inverse_of :a
has_many :bs, :through => :relationships
# returns array of hashes, not json string, of all Relationship's and B's attributes
def relationshipValues
# get all of a's relationships, including `b`s with only 2 queries
relationships = Relationship.includes(:b).where(a_id: :id).all
relationshipValues = []
# I'm not sure if this is optimal, so please offer some advice
@relationships.each do |relationship|
relationshipValues << relationship.attributes.merge(relationship.b.attributes)
end
# simple return - is there better way?
relationshipValues
#just for spacing :)
end
end
class B < ActiveRecord::Base
has_many :relationships, :inverse_of :b
has_many :as, :through => :relationships
end
class Relationship < ActiveRecord::Base
belongs_to :a, inverse_of: :relationships
belongs_to :b, inverse_of: :relationships
def to_json
attributes.merge(b.attributes)
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.