Jump to content

The ultimate community for Ruby on Rails developers.


Photo

NameError: undefined local variable or method `email' for #<Class:0x007fc3f35c4fe0>


  • Please log in to reply
9 replies to this topic

#1 ExNihil

ExNihil

    Passenger

  • Members
  • 7 posts

Posted 15 September 2013 - 11:05 PM

I'm working through chapter six of Rails Tutorial (http://ruby.railstut...ness_validation) and am stuck at listing 6.20 due to the following error occurring when I attempt to perform any CRUD activity on my database:

"NameError: undefined local variable or method `email' for #<Class:0x007f9ddf15d0b8>"

Here's my model:

 

user.rb

class User < ActiveRecord::Base
#variables
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i


#validations
validates(:name, presence: true, length: { maximum: 50 })
validates(:email, presence: true, format:{ with: VALID_EMAIL_REGEX }, uniqueness: {case_sensitive: false})


#callbacks
before_save (self.email = email.downcase)
end

I'm guessing the reference to email.downcase (specifically, the email part) is blowing something up. Is it evident to anyone precisely what I'm doing wrong?

 

 



#2 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 16 September 2013 - 02:50 AM

Use brackets { } instead of  parenthesis ( ) 

before_save { self.email = email.downcase }   

Your validates doesn't necessarily need parenthesis either. 

validates   :name, presence: true, length: { maximum: 50 }
validates   :email, presence: true, format:{ with: VALID_EMAIL_REGEX }, uniqueness: {case_sensitive: false}


#3 ExNihil

ExNihil

    Passenger

  • Members
  • 7 posts

Posted 16 September 2013 - 07:01 AM

Thanks, Rowel. Using brackets instead of parentheses did the trick.

 

I'm curious--is it a stylistic convention in Rails to not use parentheses wherever possible? I'm not the least bit opposed to it. I ask because I want to work within the conventions of the language.



#4 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 16 September 2013 - 07:29 AM

Hi ExNihil, I'm also a newbie with Rails... just started this June/July learning Ruby, then Rails.  

 

Using brackets instead of parentheses did the trick.

 

 

Brackets  { } are used to pass code blocks, and in this case you're passing the code inside { } to the validates method.  When you used parenthesis ( ), it's passing parameters/variables to the validates method... which in this case, is not what was expected. ... that's why you got the "undefined local variable" 

 

I'm curious--is it a stylistic convention in Rails to not use parentheses wherever possible? I'm not the least bit opposed to it. I ask because I want to work within the conventions of the language.

 

 

Yes, in most cases parenthesis are not needed when calling functions/methods.

In some specific cases, you need parenthesis only to force Ruby to evaluate things in the order you want. 

 

Also, sometimes curly brackets are not needed in some special circumstances, and Rails take advantage of these "features" to make everything succinct and your code clean looking.  


  • james likes this

#5 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 16 September 2013 - 11:41 AM

Just to expand on Rowels superb explanation with regards to  curly braces.

Wherever you see curly braces {} you can replace them with a do, pipe, end block

e.g.

before_save { self.email = email.downcase } 

can become

before_save do ||
  self.email = email.downcase 
end

That is a preference, but is normally used for loops where you would pass the element of an array as a variable in to the block inside the pipe. | some_var |

 

e.g.

@records.each do |record|
  record.email.downcase
end

Depends on what you find easier to read really


  • Rowel likes this

Programming is just about problem solving!


#6 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 16 September 2013 - 11:53 AM

Another example of curly braces being optional.... if a hash list is the last parameter you're passing to a method, { } are completely optional. 

 

Say your method requires (2) variables parameters, and a 3rd parameter in the form of a hash.

link_to "Click me", object_path, { :class=>"my_css_class", :id=>"my_css_id" }  

This can be rewritten as

link_to "Click me", object_path, :class=>"my_css_class", :id=>"my_css_id"

Note the  { } are gone. 

 

 

But me personally, I like to take it even further by removing the hash rocket => 

link_to "Click me", object_path, class: "my_css_class", id: "my_css_id"

For me, this looks the cleanest and less typing.  

 

NOTE: You can only remove the  { } if the hash list is the LAST parameter you're passing to a method.   



#7 Vito Botta

Vito Botta

    Signalman

  • Members
  • 12 posts
  • LocationEspoo, Finland

Posted 16 September 2013 - 03:47 PM

Another example of curly braces being optional.... if a hash list is the last parameter you're passing to a method, { } are completely optional. 

 

Say your method requires (2) variables parameters, and a 3rd parameter in the form of a hash.

link_to "Click me", object_path, { :class=>"my_css_class", :id=>"my_css_id" }  

This can be rewritten as

link_to "Click me", object_path, :class=>"my_css_class", :id=>"my_css_id"

Note the  { } are gone. 

 

 

But me personally, I like to take it even further by removing the hash rocket => 

link_to "Click me", object_path, class: "my_css_class", id: "my_css_id"

For me, this looks the cleanest and less typing.  

 

NOTE: You can only remove the  { } if the hash list is the LAST parameter you're passing to a method.   

 

 

Hi Rowel,

 

in your last example, won't "class" -using that syntax for the hash- conflict with the class keyword? I haven't tried it now so I might remember wrongly..



#8 Ohm

Ohm

    Guard

  • Members
  • 179 posts
  • LocationCopenhagen

Posted 16 September 2013 - 04:07 PM

Hi Rowel,

 

in your last example, won't "class" -using that syntax for the hash- conflict with the class keyword? I haven't tried it now so I might remember wrongly..

 

It will not, as class: and class is not the same. The first is a symbol (new Ruby 2.0 symbols in hashes) and the other is the class keyword.

 

As Rowel mentions, you can use class: "my_class" instead of :class => "my_class". They are the same.


Blog: http://ohm.sh | Twitter: madsohm


#9 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 16 September 2013 - 04:09 PM

No it wouldn't conflict.  

In fact, it's a "dummy"...  you can put anything you want, like   something: "blah-blah"  

 

and the resulting HTML will just append that whole hash list inside the HTML angle brackets. 

 

< ....    something="blah-blah" > 



#10 Vito Botta

Vito Botta

    Signalman

  • Members
  • 12 posts
  • LocationEspoo, Finland

Posted 16 September 2013 - 04:10 PM

Cool, OK. I seemed to remember some related error but it must have been something else :)






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users