Rails模型多个has_many:通过关系输出到json

时间:2013-09-01 04:57:37

标签: ruby-on-rails json

我有以下数据模型,并希望呈现包含每个模型的信息的json哈希。例如,client.id,client.name_first,client,name_last,每个客户的每个锻炼描述以及每个锻炼的每个锻炼描述。

class Client < ActiveRecord::Base
  belongs_to :account
  belongs_to :trainer
  has_many :programs
  has_many :workouts, :through => :programs
end

class Workout < ActiveRecord::Base
  has_many :programs
  has_many :clients, :through => :programs
  has_many :routines
  has_many :exercises, :through => :routines
end

class Exercise < ActiveRecord::Base
  has_many :routines
  has_many :workouts, :through => :routines
end

我的数据库迁移:

class CreateClients < ActiveRecord::Migration
  def change
    create_table :clients do |t|
      t.integer :account_id
      t.integer :trainer_id
      t.string :name_first
      t.string :name_last
      t.string :phone

      t.timestamps
    end
  end
end

class CreateWorkouts < ActiveRecord::Migration
  def change
    create_table :workouts do |t|
      t.string :title
      t.string :description
      t.integer :trainer_id

      t.timestamps
    end
  end
end

class CreateExercises < ActiveRecord::Migration
  def change
    create_table :exercises do |t|
      t.string :title
      t.string :description
      t.string :media

      t.timestamps
    end
  end
end

我可以返回特定客户的锻炼:

@client = Client.find(params[:id])
clients_workouts = @client.workouts.select('workouts.*,programs.client_id').group_by(&:client_id)
render json: clients_workouts

我能够为特定的锻炼恢复锻炼:

@workout =  Workout.find(params[:id])
exercises_workouts = @workout.exercises.select('exercises.*, routines.workout_id').group_by(&:workout_id)
render json: exercises_workouts

但是,我不知道如何使用包含的所有三个表(客户端,锻炼,练习)中的信息(通过程序和例程加入)返回数据。这可能吗?它是如何完成的?

2 个答案:

答案 0 :(得分:2)

首先,我不确定您的查询中发生了什么:

clients_workouts = @client.workouts.select('workouts.*,programs.client_id').group_by(&:client_id)

这还不够吗?

@client.workouts

现在,回答......假设我还在关注:

ActiveRecord提供了.to_json方法,这是在这里隐式调用的方法。显式版本将是例如。

render json: clients_workouts.to_json

知道了,你可以在api中查找to_json(这里有一些很好的文档,即使它显示为已弃用:http://apidock.com/rails/ActiveRecord/Serialization/to_json)。但是,基本上,答案是从根对象开始 - 我相信客户端 - 并在选项哈希中构建包含的对象和属性/方法。

render json: @client.to_json(include: { workouts: { include: :exercises } })

如果需要,您可以自定义每个相关模型中包含的属性或方法,只需稍微深入了解文档。玩得开心!

答案 1 :(得分:0)

非常可能,他们有不同的方式来做到这一点。

一,没有任何第三方库就是使用包含,就像你正在解决一个n + 1问题或... ...

使用更冷却的方法并使用活动模型序列化程序

Active Model Serializers