Search code examples
ruby-on-railsruby-on-rails-3nested-resources

Variable calling in rails views


I just finished adding nested resource to my Ruby on Rails application.

It was mostly will guessing, copying and pasting.

Everything works now.

But my concern is that while using url helpers, I had to use two different variable forms -- one with @ at the start, and one without @.

In my partial, I used:

=> link_to t('ui.edit'), edit_course_lesson_path(@course, lesson)

In case I add '@' before lesson, I got the following error:

Routing Error

No route matches {:action=>"edit", :controller=>"lessons", :course_id=>#<Course id: 2,
title: "title x", user_id: 1, subject_id: 1, student_level_id: 1, objectives: "obj xx",
created_at: "2013-08-09 15:51:38", updated_at: "2013-08-09 15:51:38">, :id=>nil}

Try running rake routes for more information on available routes.

And in my regular views:

=> link_to t('ui.edit'), edit_course_lesson_path(@course, @lesson)

At last example, if I write course without '@', then I get:

undefined local variable or method `course' for #<#<Class:0x007f5e10082800>:0x007f5e10a64760>

Just wanted to know the difference of adding or omitting '@' in views. Probably, the key factor here is partial vs regular view.

Thank you very much!

PS: Also, I found this post useful on nested resources subject:

http://blog.8thcolor.com/2011/08/nested-resources-with-independent-views-in-ruby-on-rails/


Solution

  • The @ denotes an instance variable, set in your controller for an instance of your model. Some views will call a partial for instance:

    = render @courses
    

    Will call a partial called _course.html.haml (or erb or slim) and automatically pass it a local variable for each render.

    Inside that partial, you use are using a local variable course, e.g.

    = course.subject.title
    = course.title
    

    So in a standard view rendered by your controller you'll typically use instance variables so they are available across the controller action, meaning it can be used in partials called by your view whereas local variables cannot.