2013-10-01 8 views
0

Вот моя модель пользователяметод сохранения не записи в базу данных

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    has_many :personas 
    has_many :stories, through: :persona 

    validates_presence_of :name 

    attr_accessor :name, :default_persona_id 
    after_create :create_first_persona 

private 
    def create_first_persona 
    @persona = Persona.new 
    @persona.user = self 
    @persona.name = self.name 
    if @persona.save 
     make_first_persona_default 
    end 
    end 

    def make_first_persona_default 
    @user = self 
    @user.default_persona_id = @user.personas.first.id 
    @user.save!(:validate => false) 
    end 
end 

Что она делает это создать Persona каждый раз при входе пользователя и затем устанавливает, что идентификатор Persona как default_persona_id пользователя.

Все работает, кроме make_first_persona_default. Когда я проверяю пользователя в консоли rails, default_persona_id равен нулю.

Я на Rails 4.

UPDATE

Отредактировано make_first_persona_default на Taryn Востоке

def make_first_persona_default 
    unless self.update_attribute(:default_persona_id, self.personas.first.id) 
     raise "got an error trying to save persona: #{self.errors.inspect}" 
    end 
    end 

default_persona_id по-прежнему ноль

User Load (1.0ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1 
=> #<User id: 13, email: "[FILTERED]", encrypted_password: "[FILTERED]", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2013-10-01 02:09:19", last_sign_in_at: "2013-10-01 02:09:19", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2013-10-01 02:09:19", updated_at: "2013-10-01 02:09:19", default_persona_id: nil> 

Вот моя схема для пользователя ,

create_table "users", force: true do |t| 
    t.string "email",     default: "", null: false 
    t.string "encrypted_password",  default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   default: 0, null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "default_persona_id" 
    end 

и миграция, которую я использовал для добавления столбца default_persona_id.

class AddActivePersonaToUsers < ActiveRecord::Migration 
    def change 
    change_table :users do |t| 
     t.integer :default_persona_id 
    end 
    end 
end 

ответ

2

Интересно, что эта линия делает в вашей User модели:

attr_accessor :name, :default_persona_id 

Возможно, вы имели в виду accessible? Таким образом, создание аксессуаров переопределит ActiveRecord accessor, поэтому присвоение default_persona_id задает только переменную экземпляра @default_persona_id и не повлияет на базу данных.

+0

Ах! Позвольте мне попробовать. –

+0

В этом была проблема! –

1

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

Я хотел бы сделать это следующим образом:

private 
    def create_first_persona 
    persona = self.personas.build(:name => self.name) 
    if persona.save! 
     self.update_attribute(:default_persona_id, persona.id) 
    end 
    end 

Если вы хотите продолжить с двумя методами образом, сборка поможет с этим. Я подозреваю, что проблема в вашем исходном коде заключается в том, что вы не строите связь - и поэтому «personas» нуждается в перезагрузке, прежде чем пользователь сможет найти новую персону.

Также вам не нужно выбивать текущего пользователя так, как вы делаете. У вас уже есть я, поэтому просто используйте self. например:

def make_first_persona_default 
    self.default_persona_id = self.personas.first.id 
    self.save!(:validate => false) 
    end 

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

def make_first_persona_default 
    self.update_attribute(:default_persona_id, self.personas.first.id) 
    end 
+0

Ошибка при получении первого фрагмента при сохранении @persona. Я полагаю, вы хотите проверить self.update_attributes? –

+0

Обновлен мой вопрос, чтобы включить дополнительную информацию. Кстати, update_attributes собирается обходить проверку имени? –

+0

Нет. Но к тому моменту, когда вы доберетесь до этого момента, вы уже запустили и закончили «создать», чтобы он уже был действительным.Если это недействительно - код будет неудачен задолго до перехода к hook_ after. –

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