2013-06-04 4 views
3

Я пытаюсь сделать в рельсах консолиНевозможно инициализировать объект ActiveRecord

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

Мой класс Пользователь выглядит

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 

Я следую вместе с rails tutorial. Почему я не могу инициализировать объект?

+0

в соответствии с вашим учебным пособием, они просят вас использовать «имя:», «по электронной почте:« »' не ': name =>" ",: email =>" "' это может быть вашей проблемой? – sircapsalot

+0

Я думал, что это может быть проблемой. Но я пробовал оба стиля без успеха. – gprasant

ответ

4

TL; др: Скопировать именно из этой книги, и вы должны быть в порядке.

Пример в вопросе от Chapter 4 в Ruby on Rails Tutorial book и не Активной модели Записи: (Примечания Я автор.). В частности, класс пользователя отображается в вопросе основывается на 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 

Этот класс делает не наследоваться от ActiveRecord::Base, а должны быть включены непосредственно в консоль с помощью require './example_user.rb', как описано в Section 4.4.5. Поведение, которое вы видите, является результатом включения < ActiveRecord::Base в первую строку, но если вы скопируете код в Listing 4.9, вы должны увидеть ожидаемое поведение.

+0

mhartl, спасибо за ответ. Я на самом деле смотрю на Ch 6, а не на Ch 4. И в листинге 6.2 сказано User gprasant

+0

Код, который вы используете, представляет собой путаную комбинацию класса User из главы 4 и ActiveRecord :: Base из главы 6. ​​Нигде в книге ActiveRecord :: Base всегда сочетается с «def initialize», «def formatted_email» и т. д. Другими словами, tl; dr по-прежнему применяется: копируйте именно из книги, и все должно быть в порядке. – mhartl

+0

вы были правы. Проблема заключалась в том, что у меня была информация о поле, дублируемая как в классе модели, так и в классе миграции. Позволяет мне не сушить вещи. Почти потерянная вера в рельсы! – gprasant

2

Вы используете консоль в том же каталоге файлов, что и ваш проект? Я также попробовал бы перевести нотацию в пример, использованный в книге, и посмотреть, доставит ли она вас в любом месте.

Вы также можете попросить пользователя User.new без атрибутов и посмотреть, генерирует ли он объект, указанный в 6.1.3 учебника, а затем заполнить его и посмотреть, работает ли он.

также убедитесь, что у вас нет валидации вашего имени пользователя в вашей модели.

и последний чек вы можете запустить user.error, чтобы понять, почему это не может быть экономия

0

Вы используете консоль с помощью команды rails c для загрузки среды из корневого каталога вашего проекта? Ввод irb для запуска сеанса консоли не загружает среду приложения Rails.

Вот еще несколько советов по устранению неполадок

  • Проверьте, чтобы убедиться, что база данных разработки, указанные в config/database.yml работают
  • Проверьте, чтобы убедиться, что миграция существует, чтобы создать таблицу пользователей
  • Проверьте, чтобы убедитесь, что миграции выполнены с помощью rake db:migrate
  • Убедитесь, что таблица фактических данных существует в базе данных с столбцами типа varchar (или text) для поля: имя и: адрес электронной почты
+0

Пробовал все ваши советы по устранению неполадок. Все равно никакого результата. Его довольно 3-трубная проблема – gprasant

2

Во-первых, я предполагаю, что модель User сохраняется в вашем приложении Rails. Это означает, что у вас уже есть мигрировали User перед запуском rails console.
Если таблица не существует, вам будет предложено instanly с:

=> Пользователь (таблица не существует)

Теперь давайте повеселимся в rails console:
Прежде всего, не переопределяйте метод initialize в модели Rails; При создании метода инициализации объекта из ActiveRecord имеет приоритет (я думаю), поэтому он может создавать конфликты. Вместо этого используйте обратный вызов after_initialize. В консоли:

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 

Теперь

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]>" 

Все сделано! Милая.

UPDATE:
В соответствии с вашей недавней gist; Я не вижу смысла иметь after_initialize. Rails делает это самостоятельно.
Прежде всего, замените attr_accessor на attr_accessbile.
attr_accessor - метод ruby ​​(любезность, метапрограммирование), который создает геттер и сеттер для предоставленной переменной экземпляра. Rails использует для этого attr_accessible; для соображений безопасности только переменные экземпляра, разрешенные в attr_accessible, допускают массовое присвоение (путем отправки хэша параметров).

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 
+0

Пробовал ваши предложения. Пока не повезло :-( Хеш gist https://gist.github.com/gprasant/e9d454bc0246dbba1e18 – gprasant

+0

в соответствии с вашим суждением, я изменил ответ выше. Это, безусловно, поможет вам. – kiddorails

Смежные вопросы