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

它的作用是在每次用户注册时创建一个角色,然后将该角色的 id 设置为用户的 default_persona_id。

一切正常,除了make_first_persona_default. 当我在 Rails 控制台中检查用户时,default_persona_id 为 nil。

我在 Rails 4 上。

更新

将 make_first_persona_default 编辑为 Taryn East 的

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
4

2 回答 2

2

我想知道这条线在你的User模型中做了什么:

attr_accessor :name, :default_persona_id

你的意思是accessible?以这种方式创建访问器将覆盖ActiveRecord访问器,因此分配default_persona_id只会设置实例变量@default_persona_id,不会对数据库产生影响。

于 2013-10-01T02:37:17.253 回答
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

如果您希望继续使用这两种方法,构建将对此有所帮助。我怀疑您原始代码中的问题是您没有建立关联 - 因此“角色”需要重新加载,然后用户才能找到新角色。

此外,您不需要以您的方式获取当前用户..您已经拥有自我,所以只需使用自我。例如:

  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
于 2013-10-01T00:21:21.570 回答