简体   繁体   English

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

[英]Add nested attribute to associated model in Rails

I have three models using Active Record associations: 我有三种使用Active Record关联的模型:

Book Model
has_many :checkouts

User Model
has_many :checkouts

Checkout Model
belongs_to :book
belongs_to :user

In my view, I need the book, checkout, and user names from the checkouts. 在我看来,我需要账簿,结帐和结帐中的用户名。

By using Book.first.checkouts I get: 通过使用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">
  ]>

But, I would like to the user name, not just the id. 但是,我想输入用户名,而不仅仅是ID。 I've tried Book.first.checkouts.map { |c| c.user.name } 我已经尝试过Book.first.checkouts.map { |c| c.user.name } Book.first.checkouts.map { |c| c.user.name } but that returns only the name, and I need the rest of the checkout information. Book.first.checkouts.map { |c| c.user.name }但只返回名称,我需要其余的结帐信息。 Ideally, my data (converted to json) looks something like: 理想情况下,我的数据(转换为json)如下所示:

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

How can I add the user name to my checkout data? 如何将用户名添加到我的结帐数据中?

您可以在控制器上尝试:

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

You should preload the data to prevent (N+1) query problem, For Display possible checkouts for particular book: 您应该预加载数据以防止(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

To include other solutions, I found this worked pretty well: 为了包括其他解决方案,我发现这很好用:

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 did the trick. attributes.merge起到了作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM