正确使用.includes和.joins

时间:2013-02-16 17:23:56

标签: ruby-on-rails rails-activerecord

我有3个模特

选项:

class Option < ActiveRecord::Base
  attr_accessible :key, :name
  belongs_to :item_options
end

ItemOptions

class ItemOption < ActiveRecord::Base
  # attr_accessible :title, :body
  belongs_to :item
  belongs_to :option
end

和项目:

class Item < ActiveRecord::Base
  has_many :item_options
  has_many :options, :through => :item_options
end

我需要我的控制器以JSON格式返回所有带有选项的项目,所以我试图使用.includes但没有运气:

items = Item
  .order('id')
  .where(manufacturer)
  .where('is_active')
render :json => {:data => items.offset(offset), :total => items.count}.to_json(
  :include => :options
)

结果不包含选项,但我在控制台中看到有适当的数据库请求。但是它只有在我使用时才有效:include to_json:

items = Item
  .order('id')
  .where(manufacturer)
  .where('is_active')
render :json => {:data => items.offset(offset), :total => items.count}.to_json(
  :include => :options
)

所以第一个问题是我做错了什么,以便.include不起作用?

但我也有工作代码的问题。我需要与item_options连接的选项,因为当item_options为定义的项目的已定义选项保留值时,options只存储选项名称,选项组ID等。所以我试图扩展我的代码如下:

items = Item
  .order('id')
  .where(manufacturer)
  .where('is_active')
render :json => {:data => items.offset(offset), :total => items.count}.to_json(
  :include => {
    :options => {
      :joins => :item_options
    }
  }
)

但是,我还是收到了与item_options不相关的选项。为什么呢?

另外如果我在optoins中使用连接,我是否需要在item_options中加载没有附加信息的项目中定义has_many?

==========更新:

现在我只是在项目模型中替换了options方法的关系:

item = Item
  .includes(:item_options)
  .find(params[:id])
render :json => item.to_json(:methods => :options)

并在项目模型中:

has_many :item_options
def options
  self.item_options.select('item_options.value, options.name, options.is_feature, options.root').joins('left join options on options.id = item_options.option_id')
end

但是,如果此解决方案是最佳的,则不知道。

1 个答案:

答案 0 :(得分:1)

你在哈希上调用to_json而不在模型上,而Hash对包含或连接一无所知。

尝试将json选项放在模型上

data = items.offset(offset).as_json(include: :options)
render json: {data: data, total: items.count}

此外,我认为您的Option belongs_to :item_options应为Option has_many :item_options

使用:include as_json是一个指向ActiveModel json序列化程序的指令,告诉它包含输出JSON中关联的数据。

ActiveModel::Serializers::JSONgithub

连接和包含方法是ActiveRecord的一部分,用于添加连接条件并执行预先加载。

ActiveRecord joins
ActiveRecord includes