Search code examples
ruby-on-railsrubyrabl

Access model method from rabl template


I'm trying to access a model method in a Ruby on Rails rabl template but I'm having trouble figuring out how to pass in an argument to the function. Here's the model code -

class Conversation < ActiveRecord::Base
    has_many :messages, dependent: :destroy
    belongs_to :sender, foreign_key: :sender_id, class_name: User
    belongs_to :recipient, foreign_key: :recipient_id, class_name: User

  def opposed_user(user)
    user == recipient ? sender : recipient
  end

end

And here's my rabl template file -

collection @conversations, object_root: false
attributes :id, :sender_id, :recipient_id

node :otheruser do |c|
    c.opposed_user(current_user)
end

Specifically it's the opposed_user that I'm trying to return but the error I'm getting with the above is wrong number of arguments (0 for 1). current_user is returning the correct user ok so is this is simple thing or am I going about it in the wrong way?

Update

If I use c.opposed_user(current_user).to_json it works however the json is returning an escaped string rather than the actual json object. I think maybe I need to use child instead of node but not sure.


Solution

  • It sounds like you were fairly close to solving this. You can use as_json instead of to_json to fix the RABL template you already have.

    The final template would look like this:

    collection @conversations, object_root: false
    attributes :id, :sender_id, :recipient_id
    
    node :otheruser do |c|
      c.opposed_user(current_user).as_json
    end
    

    With RABL, there are a number of different ways to handle things. When you use node, it will simply add one key if you provide a string. Since to_json returns a string, you end up with something like { otheruser: "whatever string you provided" }.

    However, if you use as_json, you'll end up providing a hash which node can also handle. For example, like this:

    node :otheruser do |c|
      { id: 1, name: 'Bob' }
    end
    

    You'll end up with JSON that looks like: { otheruser: { id: 1, name: 'Bob' } }. Here's a link to the documentation on node in RABL.