[英]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.