我正在开发一个具有某种新闻源功能的网站。我想从表中提取包含项目和数据的表中的数据,然后将这些数据的一部分组合成JSON响应。两者都是哈希数组。我不想采取所有这些领域,只有部分。
我以为我会拉两个完整记录然后在一个方法中进行组合,以便只打两次DB。我可以轻松地将最后5个项目拉出来:
class NewsfeedsController < ApplicationController
before_action :authenticate_user!
def index
@newsfeed_data = json_response(return_items(params[:limit]))
end
private
def return_items(limit)
output = Item.last(limit=limit).reverse
end
end
现在我被卡住了。我不知道如何从输出中删除不需要的项目或如何将其与用户数据相结合。项目属于模型中的User,因此有一个user_id字段链接它们。
以下是项目和用户的模式
create_table "items", force: :cascade do |t|
t.string "name"
t.text "description"
t.string "type"
t.json "properties"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_items_on_user_id", using: :btree
end
create_table "users", force: :cascade do |t|
[lots of Devise settings...]
t.string "first_name"
t.string "last_name"
t.string "company"
t.string "position"
t.string "email"
t.json "tokens"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "avatar"
[indexes...]
end
这是我想要的输出:
{
"name": "Item name",
"type": "Item type",
"first_name": "User owner's first name",
"company": "User's company",
"avatar": "URL string to saved image"
}
答案 0 :(得分:2)
最干净,最易维护的方法是使用ActiveRecordSerializers
宝石。
app/serializers/newsfeeds_serializer.rb
在该文件中,定义一个如下所示的序列化程序:
class NewsfeedsSerializer < ActiveModel::Serializer
attributes :name, :type, :first_name, :company, :avatar
def first_name
object.user.first_name
end
def company
object.user.company
end
def avatar
object.user.avatar
end
end
在您的控制器中,按如下方式编写索引路径:
class NewsfeedsController < ApplicationController
before_action :authenticate_user!
def index
@items = Item
.order(created_at: :desc)
.limit(params[:limit])
.includes(:user)
render json: @items, each_serializer: NewsfeedsSerializer
end
end
这将使用我们在序列化程序中定义的方法序列化每个Item
对象。使用:includes会预加载每个User
所属的Item
项,因此我们将使用的所有内容都会在一次数据库调用中被抓取。
如果您想要编辑您要发送的JSON,可以轻松更改序列化程序。如果您遇到任何设置问题或想要更多自定义配置(camelCased
密钥或类似内容),我建议您阅读ActiveModelSerializer guides they provide。
答案 1 :(得分:1)
你可以做这样的事情,但是rails可能已经构建了一些用于提取JSON响应的东西。
def return_items(limit=10)
items = Item.includes(:user).select('user_id, name, type, etc_you_want_to_pick').first(limit)
response = []
items.each do |item|
response << {
"name": item.name,
"type": item.type,
"first_name": item.user.first_name,
"company": item.user.company,
"avatar": item.user.avatar
}
end
return response
end
如果您可以将整个用户放在哈希中,那么可以使用相同的AR查询,然后在集合上调用.as_json。