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 はまだ nil です

  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

2 つの方法で続行する場合は、ビルドが役立ちます。元のコードの問題は、関連付けに基づいていないことにあると思われます。したがって、ユーザーが新しいペルソナを見つける前に、「ペルソナ」をリロードする必要があります。

また、現在のユーザーを取得する必要はありません..すでに自分自身を持っているので、自分自身を使用してください。例えば:

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

またはさらに良いことに、属性を 1 つしか設定していないので、更新属性を使用します

  def make_first_persona_default
    self.update_attribute(:default_persona_id, self.personas.first.id)
  end
于 2013-10-01T00:21:21.570 に答える