将嵌套属性添加到R​​ails中的关联模型

时间:2017-04-25 17:39:55

标签: ruby-on-rails ruby activerecord associations

我有三个使用Active Record关联的模型:

Book Model
has_many :checkouts

User Model
has_many :checkouts

Checkout Model
belongs_to :book
belongs_to :user

在我看来,我需要结帐中的书籍,结帐和用户名。

使用Book.first.checkouts我得到:

#<ActiveRecord::AssociationRelation
  [#<Checkout id: 30,
    checkout_date: "2017-04-13",
    return_date: nil,
    book_id: 118,
    user_id: 1,
    created_at: "2017-04-13 17:43:07",
    updated_at: "2017-04-13 17:43:07"
  >,#<Checkout id: 50,
    checkout_date: "2017-04-13",
    return_date: nil,
    book_id: 118,
    user_id: 1,
    created_at: "2017-04-14 00:33:34",
    updated_at: "2017-04-14 00:33:34">
  ]>

但是,我想要用户名,而不仅仅是id。我已经尝试Book.first.checkouts.map { |c| c.user.name },但只返回名称,我需要其余的结帐信息。理想情况下,我的数据(转换为json)看起来像:

{
  name: "Book Name",
  checkouts:  [
    checkout_data: "Today",
    user_name: "Mary"
  ]
}

如何将用户名添加到我的结帐数据中?

3 个答案:

答案 0 :(得分:1)

你可以在你的控制器上试试这个:

render json: @books, include: { checkout: { only: :checkout_date, include: { user: { only: :name } } }}

答案 1 :(得分:0)

您应该预加载数据以防止(N + 1)查询问题, 用于显示特定图书的可能结帐:

book_id = <given book id>
book = Book.find(book_id)
checkouts = book.checkouts.includes(:user)
return_hash = {name: book.name, checkouts: []}
checkouts.each do |checkout|
    return_hash[:checkouts] << { checkout_data: checkout.checkout_date,
                                 user_name: checkout.user.name
                               }
end

答案 2 :(得分:0)

为了包含其他解决方案,我发现这很有效:

checkouts = book.checkouts.unreturned.map do |checkout|
  checkout.attributes.merge({ user_name: checkout.user.name })
end

{ checkouts: checkouts, available: book.available?, book_id: book.id }

attributes.merge成功了。