-
Notifications
You must be signed in to change notification settings - Fork 333
Referencing objects in extended views
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 show.rabl
view.
# 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 index.rabl
view.
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.