I'm currently working on a personal Rails 4 project, and in one of the controllers, I have an array of three different objects, which I'm trying to convert into JSON. I'm using the find_by_sql
method to query the DB with a custom MySQL query. The code is as follows:
The controller:
class ActivitiesController < ApplicationController
def index
user = current_user.id # using devise
limit = 100
likes = Like.find_by_sql(...)
shares = Share.find_by_sql(...)
comments = Comment.find_by_sql(...)
@activities = [likes, shares, comments]
end
end
Each of the three objects contain different fields. For example, the likes
object contains fields such as post_id , first_name , last_name etc. The shares
object contains fields such as post_id , share_count , shared_time etc.
This is the JSON I want to output:
{
"likes": [
{ "post_id": "7", "first_name": "Yss", "last_name": "Salas", "profile_pic": "345943754_o.png" },
{ "post_id": "34", "first_name": "Jessica", "last_name": "Nigri", "profile_pic": "pikachu.png" }
],
"shares": [
{ "post_id": "43", "share_count": 54, "shared_time": "2014-05-04 15:14:45" },
{ "post_id": "54", "share_count": 17, "shared_time": "2014-05-24 03:43:45" }
],
"comments": [
{ "post_id": "34", "first_name": "Yss", "last_name": "Salas", "comment": "¡Me gustas mucho!" },
{ "post_id": "12", "first_name": "Jenna", "last_name": "Marbles", "comment": "Blah blah blah look at my ugly dog awwwww!" }
]
}
The index.json.jbuilder:
json.array! @activities do |subactivities|
json.array! subactivities do |activity|
if activity.class == Like
json.likes.post_id activity.post_id #exception raised in this line
json.likes.title activity.title
json.likes.first_name activity.first_name
json.likes.last_name activity.last_name
json.likes.profile_pic activity.profile_pic
elsif activity.class == Share
json.shares.post_id activity.post_id
json.shares.share_count activity.share_count
json.shares.shared_time activity.shared_time
else
json.comments.post_id activity.post_id
json.comments.first_name activity.first_name
json.comments.last_name activity.last_name
json.comments.comment activity.comment
end
end
end
The above raises an exception NoMethodError in Activities#index, undefined method 'post_id' for #<Object:0x00000003064250>
. I'm very new to Rails, and I'm guessing that this is happening because there is no json.likes
property to assign the values to. How do I go about building the above JSON structure with JBuilder?
You can do it without JBuilder, easier and faster.
def index
user = current_user.id # using devise
limit = 100
likes = Like.find_by_sql(...).map(&:attributes) # this will return an array of JSON objects
shares = Share.find_by_sql(...).map(&:attributes)
comments = Comment.find_by_sql(...).map(&:attributes)
@activities = {"likes" => likes, "shares" => shares, "comments" => comments}
end
Like this you have a hash with all the information you need. It may also be better to extract the logic of looking for likes, shares and comments to a separate class, so that you would call InformationCollector.collect
and it will give you the response you need.
From Jbuilder's GitHub page , the solution is rather simple. All that needs to be done is pass the instance variables into a block, and assign the custom key/value pairs manually.
The below example would generate an array of key/value pairs for the @likes
instance variable:
# activities/index.json.jbuilder
json.likes @likes do |like|
json.post_id like.post_id
json.first_name like.user.first_name
json.last_name like.user.last_name
json.profile_pic like.user.profile_pic
end
The above will output:
{
"likes": [
{ "post_id": 7, "first_name": "Yss", "last_name": "Salas", "profile_pic": "345943754_o.png" },
{ "post_id": 34, "first_name": "Jessica", "last_name": "Nigri", "profile_pic": "pikachu.png" }
],
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.