清除带有关联的ActiveRecord对象的方法

问题描述 投票:0回答:1

我想只返回没有asscoiation_id的所有Thing模型对象,有没有includeexcept的更好的方法呢?

# Thing.rb

belongs_to :object_a
belongs_to :object_b

# create_thing.rb

def change
  create_table :things, id: false do |t|
    t.string :id, limit: 36, primary_key: true
    t.string :object_a_id, foreign_key: true
    t.string :object_b_id, foreign_key: true

    t.timestamps
  end
end
# things_controller.rb

render json: Thing.all, include: [:object_a, :object_b]

output => {
  id: ....
  object_a_id: 'object_a_id',
  object_b_id: 'object_b_id',
  object_a: {
    id: object_a_id
    ...
  },
  object_b: {
    id: object_b_id
    ...
  }

我知道我可以这样做以获得我想要的东西,但我想知道是否有一种DRY方式可以做到这一点,而无需包含所有include和except。

render json: Thing.all, include: [:object_a, :object_b], except: [:object_a_id, :object_b_id]

output => {
  id: ....
  object_a: {
    id: object_a_id
    ...
  },
  object_b: {
    id: object_b_id
    ...
  }

ruby-on-rails activerecord activemodel
1个回答
0
投票

模型中主要使用DRY方法,您可以定义attributes方法,并使其返回要使用渲染函数的对象的形状。

# thing.rb

def attributes
  # Return the shape of the object
  # You can use symbols if you like instead of string keys
  {
    'id' => id,                      # id of the current thing
    'other_fields' => other_fields,  # add other fields you want in the serialized result   
    'object_a' => object_a,          # explicitly add the associations
    'object_b' => object_b
  }
end

关联object_aobject_b应该像正常情况一样序列化。如果要限制/自定义其序列化结果,可以通过在它们各自的类中添加attributes方法来为它们重复相同的方法。

因此,当在单个事物模型或事物模型的集合上调用render json:时,返回的json对象的形状将与上述方法中定义的一样。

注意:

一个警告是,您在attributes中返回的哈希中的键名必须与方法名(或关联名)匹配。我不太清楚为什么。但是,当需要添加名称与其对应列不同的键时,我使用的解决方法是在要使用的键名称模型中创建一个方法。

例如,假设您的Thing模型具有一列name,但是在json结果中,您希望将与该列相对应的键名称为name_of_thing。您将执行以下操作:

def name_of_thing
  name
end

def attributes
  {
    'name_of_thing' => name_of_thing,
    # other fields follow
    # ...
  }
end
© www.soinside.com 2019 - 2024. All rights reserved.