Reputation: 61
I'm using Rails 4.I'm creating API databse where users can sign up from Facebook Graph API. If user has no profile picture then the image_url is null.
After reading answers in SO I thought this is the correct way how to build custom json for my response.
I have created method as_json to render response when user is created with only parameters who should get returned. This is the method how I'm creating json response:
def as_json(options={}){
id: self.id,
first_name: self.first_name,
last_name: self.last_name,
auth_token: self.auth_token,
image: {
thumb: "http://domain.com" + self.profile_image.thumb.url
}
}
end
This method above gives me an error: no implicit conversion of nil into String
.
I need to give absolute image url path if the image exists in my db, but i don't need to give this parameter in response if image url is null in my database. How can I write if statement inside this as_json method? I've tried this, but it doesn't work.
def as_json(options={}){
id: self.id,
first_name: self.first_name,
last_name: self.last_name,
auth_token: self.auth_token,
if !self.profile_image.thumb.url == nil
image: {
thumb: "http://domain.com" + self.profile_image.thumb.url
}
end
}
end
With the help from Jorge de los Santos I've managed to make it pass no implicit conversion of nil into String
error with this code:
def as_json(options={})
response = { id: self.id,
first_name: self.first_name,
last_name: self.last_name,
auth_token: self.auth_token }
if !self.profile_image.thumb.url == nil
image = "http://domain.com" + self.profile_image.thumb.url
response.merge(image: {thumb: image })
end
response
end
But now all the users are returned without image parameter even when he has a image url.
Upvotes: 0
Views: 1820
Reputation: 4633
You can't use logic inside a hash key, you can declare the variable before returning the hash, or you can use the full statement inside the value of the hash. But I think this is more readable.
def as_json(options={})
response = { id: self.id,
first_name: self.first_name,
last_name: self.last_name,
auth_token: self.auth_token }
image = "http://domain.com" + self.profile_image.thumb.url
response.merge!({image: {thumb: image }}) unless self.profile_image.thumb.url
response
end
Upvotes: 0
Reputation: 42869
Using Jbuilder
When you are building a complex json object, it's better to use jbuilder, I'll assume the model is called 'User'
Create a template called show.json.jbuilder
json.id @user.id
json.first_name @user.first_name
json.last_name @user.last_name
json.auth_token @user.auth_token
unless @user.profile_image.thumb.url.nil?
json.image do |image|
image.thumb "http://domain.com#{@user.profile_image.thumb.url}"
end
end
I would recommend creating a helper for the image url, so we could for example call something like
json.image @user.full_profile_image_url
As for your own method (using as_json) you could create a method that returns the full image hash
class User < ActiveRecord::Base
def image
{ thumb: "http://domain.com#{profile_image.thumb.url}" }
end
end
Then in the as json call the method
@user.to_json(
only: %i(id first_name last_name auth_key),
methods: :image
)
This will call the image method and set it's value inside a key called 'image'
Upvotes: 1
Reputation: 11137
Your code seems fine except when you try to merge image key, merge function is not working as you expect, check the followingt to understand:
hash = {a: 1, b:2 }
hash.merge(b: 3)
puts hash #{a: 1, b:2 }
hash = hash.merge(b: 3)
puts hash #{a: 1, b:2, c: 3 }
so you will need to modify your code by changing this line:
response.merge(image: {thumb: image })
to
response = response.merge(image: {thumb: image })
Upvotes: 1