28

I am using the to_json method on an object, and trying to get the :methods argument to work. I have a method on my model (Drop) called is_favorited_by_user?. This method takes an argument of the current_user, and then checks to see if the drop is favorited by the user. How can I pass this argument through the to_json method.

render :json => @drops.to_json(:methods => :is_favorited_by_user?(current_user))

2 Answers 2

49

You can add current_user attribute to your model and set it before executing to_json

  attr_accessor :current_user

  def is_favorited_by_user?(user=nil)
    user ||= current_user
    # rest of your code
  end


@drops.current_user = current_user
render :json => @drops.to_json(:methods => :is_favorited_by_user?)
Sign up to request clarification or add additional context in comments.

3 Comments

How do I extend this solution when I'm doing render :json => Drop.all in the index action. Where do I assign the current_user?
cattr_accessor :current_user in model and then Model.current_user = current_user in controller.
Assigning your model to a class attribute won't work if your environment is multi-threaded. You could be in the process of converting something to JSON and then the current_user all of a sudden changes and now half your JSON is for one user and half is for another.
4

The methods to_json takes aren't intended to be ones that take arguments, but just "getter" methods. (Typically the ones created based on your db attributes.)

See examples here, none pass arguments:

http://apidock.com/rails/ActiveRecord/Serialization/to_json

If you want to do something custom, you'll need to create a method that builds up the hash of info you want, then convert that hash to json.

2 Comments

Is there a way that I can get the current_user variable within my Model, so I don't need to pass the argument?
@JamesFinley Models are not (and should not be) aware of the state of controllers or http request. current_user is part of the request and should not be exposed to models in a global way due to the multithreaded issue stated above. It should be passed only as a method parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.