Accessing the Child Instance in a Rabl Template

Accessing the child instance in a RABL template

You can access the current object by declaring the block parameter.

object @user
attributes :name
child :contacts do |contact|
if contact.is_foo?
attributes :a1, :a2
else
attributes :a3, :a4
end
end

Old answer

I ended up using the root_object method, which returns the data object in a given context.

object @user
attributes :name
child :contacts do
if root_object.is_foo?
attributes :a1, :a2
else
attributes :a3, :a4
end
end

Access model method from rabl template

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.

How to add parent attributes inside its children in rabl template?

object @parent
attributes :attr_1, :attr_2

child :child do
attributes :attr_3, :name
node(:attr_from_parent) { @parent.attr_from_parent }
end

You may also have a look at http://railscasts.com/episodes/322-rabl?view=asciicast

Rails RABL display collection as object and child in this object

Your architecture is a little bit messed up because in the show action you not only display an @exchanger but also the complete list of @currencies being nil when you render show in the index template. In general I would suggest you to think about the whole app architecture.

When I should give you a simple solution for you current problem I would extract the @currencies code from the show action into helper method in app/helpers/currencies_helper.rb and access it from the show template.

module CurrenciesHelper

def currencies(exchanger)
currencies = CurrencyList.all.map do |c|
CurrencyValue.find(:all, :conditions => {:currency_list_id => c.id, :exchanger_list_id => exchanger.id}, :order => :updated_at).last(2)
end
currencies.flatten!
end

end

By the way I replaced the each method with map because it suits better in this case.

Change the currencies part in the show template to

child currencies(@exchanger) do
attribute :value, :direction_of_exchange_id, :exchanger_list_id
end

Conditionally include child nodes with RABL

Even though the rails-rabl gem claims it is faster, I found that templates aren't as flexible for conditional expressions - see rabl-rails readme re: instance variables.

Rails – Display object and a collection in RABL template

Right from the documentation, you can include locals in partials like this example:

You can also pass in other instance variables to be used in your template as:

Rabl::Renderer.new('posts/show', @post, :locals => { :custom_title => "Hello world!" })

Then, in your template, you can use @custom_title as:

attribute :content
node(:title) { @custom_title }

This allows you to use something like:

Controller:

Rabl::Renderer.new('user/show', @user, :locals => { :posts_category => "examples" })

Partial:

attribute id
node(:posts) { |user| user.posts.by_category(@posts_category) }


Related Topics



Leave a reply



Submit