Referencing objects in extended views
Clone this wiki locally
If you're trying to DRY up your views, you may be extending views within other views. For example, you may have an
index.rabl view that just references a
# index.rabl object @rosters extends "rosters/show"
# show.rabl object @roster attributes :id, :first, :last, :number, :position
However, things get tricky if you need to reference the object within your layout, to provide conditional displays of data. For example, if you have a view like this:
# show.rabl object @roster attributes :id, :first, :last, :number, :position child ((@current_roster == self || @current_roster.is_manager) ? @roster.roster_telephones : @roster.roster_telephones.pub) => :telephone_numbers do extends "telephone_numbers/index" end
You will find that if you visit
/rosters/show, you get the information that you expect. However, if you visit
/rosters/index, you will get an error about "no such method roster_telephones for nil".
This is because, unlike you may expect, the @roster object is not getting set when the
show.rabl template is extended from within the
Instead, according to @nesquena, you should use the
node operation, which will allow you to execute a block that references the object. This code works:
# show.rabl object @roster attributes :id, :first, :last, :number, :position node :telephone_numbers do |roster| phone_numbers = ((@current_roster == roster || @current_roster.is_manager) ? roster.roster_telephones : roster.roster_telephones.pub) partial("telephone_numbers/index", :object => phone_numbers) end
This method will allow you to access the primary object in your view, no matter where it's called from.