简体   繁体   中英

How to write if statement in Rails 4 as_json method?

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.

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 })

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


Using as_json

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'

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

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.

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