Question

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/

Was it helpful?

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.

OTHER TIPS

You are very new to RoR development, right? I encourage to go completely through some beginner Rails and Ruby books, because It seems You don't understand a few basic concepts of Ruby.

The short and very approximate answer to Your question.

Variables without @ sign are local variables that exist in local scope - method scope, partial scope, view scope, block scope etc.

Variables with @ signs are instance variables - they exist in instance scope. In case of controllers and views scope is the same, so an instance variable defined in a controller action is available in Your partials, views, layouts.

A nasty thing about those that they don't throw any errors if undefined - you simply get a nil object back. And it's what actually happening in Your routing error - @lesson is nil and Rails can't construct a proper URL.

In Your second case You are trying to call a local variable that does not exist, so it throws a NoMethodError, because after not finding variable it tries to call a method of the same name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top