Ruby on rails 将关系/关联模型值添加到基础模型

Ruby on rails 将关系/关联模型值添加到基础模型,ruby-on-rails,json,ruby-on-rails-4,associations,Ruby On Rails,Json,Ruby On Rails 4,Associations,我有两个对象,A和B。使用relationshipA,每种方法都有许多其他方法relationshipA有一个属性propertyA。执行提取时,是否可以合并relationshipA和A或B的属性 比如说 A.find(params[:id]).relationshipAs 我希望它能返回我Bs,但也能将relationshipA中的属性附加到其中,至少在呈现json时是这样 class A < ActiveRecord::Base has_many :relationship_

我有两个对象,
A
B
。使用
relationshipA
,每种方法都有许多其他方法
relationshipA
有一个属性
propertyA
。执行提取时,是否可以合并
relationshipA
A
B
的属性

比如说

A.find(params[:id]).relationshipAs
我希望它能返回我
Bs
,但也能将
relationshipA
中的属性附加到其中,至少在呈现json时是这样

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
我希望:

[{
    'prop1' : 'value',
    'prop2' : 'value',
    'prop3' : 'value',
    'prop4' : 'value'
}, ...]
下面是一个控制台示例:

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'>]>
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'
*现在输出a1的所有bs,包括关系的prop4值*
#
我看到两个问题:

  • 如何生成自定义json
  • 如何带回对象以生成自定义json
  • 定义自定义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
    
    class A:关系
    结束
    B类:关系
    结束
    类关系
    这个问题很抽象。如果你能坚持使用
    关系
    对象,那么这可能是你最好的选择。使用
    includes
    将为您提供一个或两个查询


    如果您需要a
    B
    了解如何带回
    B
    ,那么您可能需要将
    attr\u accessor:prop4
    添加到
    B
    和一个“扩展”block to
    Relationship
    有许多
    子句来设置B的
    :prop4

    似乎我能做的最好的事情是对值进行散列,但不是通过初始查询或任何内置函数@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
    
    class A:关系
    #返回所有关系和B属性的哈希数组,而不是json字符串
    定义关系值
    #获取a的所有关系,包括只需2个查询的'b'
    关系=关系。包括(:b)。其中(a_id::id)。全部
    relationshipValues=[]
    #我不确定这是否是最佳的,所以请提供一些建议
    @关系。每个人都有关系|
    关系价值观:关系
    结束
    类关系
    如果我理解正确,我认为您需要根据
    id
    查询
    A
    ,然后将
    includes(:b)
    添加到呼叫中,以便包含所有
    b
    s。因此,
    A.includes(:b).find(params[:id])
    @CWitty我需要能够基于id找到
    A
    。然后我需要使用
    RelationshipA
    获得与
    A
    关联的所有
    b
    。但是,这将只返回一个
    B
    s数组,但我需要一个同时包含
    B
    RelationshipA
    s值的哈希数组。签出它可能会有所帮助。我推荐的建议应该包括A的A对象和B对象。同样在控制台示例中,我认为在a1.bs=[b1,b2]我用控制台示例更新了我的问题之后,您仍然需要调用a1.save。希望它能帮助澄清。你的两个例子我都试过了,但都没用。
    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