Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Difference between :variable and @variable

As a Ruby on Rails newbie, I understand that the "@" and ":" references have different meanings. I saw this post in SO, which described some of the differences.

  1. @ indicates a instance variable (e.g., @my_selection)
  2. : indicates an alias (e.g., :my_selection)

I ran into a situation where I had a standard MVC page, similar to all of the other forms/pages in my webapp.

html.erb snippet

<%= form_for @my_selection do |f| %>

route.rb snippet

resources :my_selections

When I attempt to access this page, I get this error:

NoMethodError in selections#create
Showing C:/somedir/myapp/app/views/my_selections/index.html.erb where line #16 raised:
undefined method `my_selection_index_path' for #<#<Class:0x1197e5676>:0x25439c3b>

Line 16 is the form snippet shown above.

All of my other forms/pages in the same web app are set up in exactly the same way and are working fine. However, once I changed the erb form reference to :my_selection, this error went away and my page behaved normally.

Questions:

  1. Is my understanding of the difference between :my_selections and @my_selections correct?
  2. Why would switching to :my_selection resolve my original error?
like image 731
JW8 Avatar asked Aug 27 '11 00:08

JW8


People also ask

What is '@' in Ruby?

The @ symbol before a variable tells Ruby that we are working with an instance variable, and @@ before a variable tells us we are working with a class variable. We use @ before a variable in instance methods within a class to tell Ruby to access that attribute (instance variable) of the instance.

What does @variable mean in Ruby?

In Ruby, the at-sign ( @ ) before a variable name (e.g. @variable_name ) is used to create a class instance variable.

What is the difference between instance variable and class variable in Ruby?

What is the difference between class variables and class instance variables? The main difference is the behavior concerning inheritance: class variables are shared between a class and all its subclasses, while class instance variables only belong to one specific class.

What are the different variables in Ruby?

Ruby has four types of variable scope, local, global, instance and class.


1 Answers

Is my understanding of the difference between :my_selections and @my_selections correct?

Nope :(

: indicates a symbol, its not an alias for anything intrinsically. It's like an immutable string, which is often used as a name to represent something.

In places where the Rails api accepts a symbol in place of an instance variable, internally it's actually doing this:

self.instance_variable_get "@#{my_symbol}"

Which actually returns the value of the requested instance variable.

So the only reason that you think symbol correspond to instance variable at all, is because the code that drives the API you are using works that way. Without a framework to do that for you, there is no correlation at all.

Why would switching to :my_selection resolve my original error?

for_form(model_instance) will generate a form that submits to the create action if the model instance is unsaved, or to the update action if the model is already exiting in your DB.

No I don't know what's in @my_selection, but whatever class it is doesn't seem to be generating the routes properly.

resources :my_selections

Will generate a route you would invoke like this:

my_selections_path

How your form is generating a route for my_selection_index_path I'm not sure and it really depends on what your models are.

And when you pass a symbol instead, and there is no corresponding ivar, it uses that as the model name for route generation. Which would do the right thing by trying to invoke my_selections_path, which is directly based on the symbol you pass in.

like image 167
Alex Wayne Avatar answered Nov 03 '22 00:11

Alex Wayne