gprasant
gprasant

Reputation: 16023

Unable to initialize ActiveRecord object

I'm trying to do in a rails console

>> user = User.new(:name => "", :email => "[email protected]")
=> #<User not initialized>

My User class looks like

class User < ActiveRecord::Base
  attr_accessor :name, :email
  has_many :microposts

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end 

  def formatted_email
    "#{@name} <#{@email}>"
  end
end

I am following along from the rails tutorial. Why am I not able to initialize the object ?

Upvotes: 3

Views: 4758

Answers (4)

mhartl
mhartl

Reputation: 1931

tl;dr: Copy exactly from the book and you should be fine. (Note: I am the author.)

The example in question is from Chapter 4 of the Ruby on Rails Tutorial book and is not an Active Record model. In particular, the User class shown in the question is based on Listing 4.9:

class User
  attr_accessor :name, :email

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end

  def formatted_email
    "#{@name} <#{@email}>"
  end
end

This class does not inherit from ActiveRecord::Base, but rather must be included explicitly in the console using require './example_user.rb', as described in Section 4.4.5. The behavior you're seeing is the result of including < ActiveRecord::Base in the first line, but if you copy the code in Listing 4.9 exactly you should see the expected behavior.

Upvotes: 4

kiddorails
kiddorails

Reputation: 13014

First, I assume that User model persists in your Rails app. That means, that you already have a migrated User model before running rails console.
If that table doesn't exist, you will be instanly prompted with:

=> User(Table doesn't exist)

Now, let's have some fun in rails console:
First things first, don't override initialize method in Rails model; While creating an object initialize method from ActiveRecord takes precedence (I think), so it may create conflicts. Instead use after_initialize callback. In console:

class User < ActiveRecord::Base
  attr_accessible :name, :email

  def after_initialize(attributes = {})
    self[:name]  = attributes[:name]
    self[:email] = attributes[:email]
  end
  def formatted_email
    "#{self.name} <#{self.email}>"
  end
end

Now,

u = User.new({name: "Foo", email: "[email protected]"})
#<User name: "Foo", email: "[email protected]", created_at:nil updated_at: nil>
u.formatted_email
#=> "Foo <[email protected]>"

All done! Sweet.

UPDATE:
As per your recent gist; I see no point of having after_initialize at all. Rails does that on it's own.
First thing first, replace attr_accessor with attr_accessbile.
attr_accessor is ruby method(courtesy, metaprogramming) which creates getter and setter for provided instance variable. Rails uses attr_accessible for that; for security concerns, only instance variables allowed in attr_accessible allowed for mass-assignment (by sending params hash).

user.rb

class User < ActiveRecord::Base
  attr_accessible :name, :email

  #def after_initialize(attributes = {})
  #  self[:name]  = attributes[:name]
  #  self[:email] = attributes[:email]
  #end 

  def formatted_email
    "#{self.name} <#{self.email}>"
  end
end

Upvotes: 2

Gui LeFlea
Gui LeFlea

Reputation: 835

Are you running console using the rails c command to load your environment from the root directory of your project? Typing irb to start a console session does not load the Rails application environment by itself.

Here are some more troubleshooting tips

  • Check to make sure that the development database specified in config/database.yml is running
  • Check to make sure a migration exists to create the Users table
  • Check to make sure the migrations have run with rake db:migrate
  • Check to make sure that a Users table actually does exist in the database, with columns of type varchar (or text) for fields :name and :email

Upvotes: 0

gr0k
gr0k

Reputation: 829

are you running your console in the same file directory as your project? I'd also try switching up the  notation to the example used in the book and see if that gets you anywhere.

you can also try calling User.new with no attributes and see if it generates an object as listed in 6.1.3 of the tutorial , and then fill in the attributes and see if it works.

also make sure you dont have a validation on your user name in your model.

and a last check you can run user.error to see why it might not be saving

Upvotes: 2

Related Questions