QA@IT

[Rails3]デフォルト値の設定についての質問です。

3592 PV

①Deviseを利用してユーザー登録機能を実装。

②ユーザーそれぞれに居住地の情報をつけたかったので新たにAddressテーブルを作成。

class Address < ActiveRecord::Base
  attr_accessible :name

  has_many :users
end

③UserテーブルとAddressテーブルの紐付け。

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

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :address_id
  # attr_accessible :title, :body

  belongs_to :address                  
end

④ここからが質問なんですが、新たに新規ユーザー登録がされたとき、address_idのデフォルト値を1にする方法が知りたいです。
マイグレーションファイルにdefaultの指定をしても上手く反映されません。

どなたか詳しい方ご回答よろしくおねがいいたします。

## 以下追記

今回の質問の本質には以下の箇所にエラーがでるためです。

NoMethodError in Microposts#index
undefined method `name' for nil:NilClass
<p>居住地:<%= @user.address.name %></p>

今回、ユーザー登録時にはアドレスとパスワードのみ、その後マイページからのリンクでプロフィール編集にとび、そこで居住地(DBに入っている文字列をプルダウンで表示)の設定を行えるという仕組みを考えています。

どうやらaddress_idに関連する文字列(address_name)になにかしらの問題があるようで、ユーザー登録後(居住地未設定の状態)にマイページに飛ぶと上記のエラーが出てしまいます。

そのため、デフォルトでaddress_idの指定をすればエラーが回避できると考えこのような質問をさせていただきましたが、それ以外に解決法があればご回答よろしくお願いいたします。駄文で申し訳ありません。

回答

お、Deviseが出てきましたね。Deviseではログインしていないときのcurrent_usernilです。current_userの内容も確認する必要がありますね。

ログイン状態とかコントローラの書き方まで絡むと検証が大変になるのでrails consoleでいろいろ確認するほうが楽です。

$ rails console
> user = User.first
> user.address_id
> user.address
> user.address.name

これは動きますか?

推測になるのですがリレーションの設定などは問題ないのだと思います。これ以上はソースコード全体を見ないとわからないですね。

編集 履歴 (0)
  • 動きました。User id:1には直接address id:14を入れていたのでそれに対応する'神奈川県'など、それぞれ表示されました。 -
  • よかったですね -
@user.address_idはundefined method`address_id' for nil:NilClass`

このエラーは@userがnilなのでaddress_idなんてわかりませんとかそんなような意味です。

次のコードがエラーになるのはわかりますよね?

@user = nil
@user.address_id

つまり@userが設定されていないだけです。対応しているコントローラで@userにUserモデルのオブジェクトを入れておきましょう。

編集 履歴 (0)
  • 何度もご丁寧にありがとうございます。@userにはcurrent_userが定義されています。当方初心者で独学のためわからないことだらけです。すみません、、、 -

追記部分見てみましたが情報が足りないので$ rails consoleでいくつか確認して教えてもらえますか?

  • @user.address_id の値
  • Address.find_by_id( 上で確認した@user.address_id ) # 例 Address.find_by_id(1) など

仮にtaichi_yano_さんが想定されている通りにaddress_idが1となっているとしたら、問題はid=1となるAddressが存在しないことになります。

編集 履歴 (2)
  • さっそくのご回答ありがとうございます。@user.address_idはundefined method`address_id' for nil:NilClassというエラーが。Address.find_by_id(1)は北海道となります。 -

Deviseが直接関係があるとは思えなかったのでDeviseを省略してサンプル環境を作って確認したところ、address_idを1にすることはできているようでした。

実施したことを以下に書いておきますので確認してみてください。
DBはデフォルト設定のsqliteです。

モデル

class Address < ActiveRecord::Base
  attr_accessible :name

  has_many :users
end

class User < ActiveRecord::Base
  attr_accessible :name

  belongs_to :address
end

マイグレーション

class CreateAddresses < ActiveRecord::Migration
  def change
    create_table :addresses do |t|
      t.string :name

      t.timestamps
    end
  end
end

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.integer :address_id, default:1, null:false

      t.timestamps
    end
  end
end

コンソールでテスト

$ rails console
> Address.create(name:"new address")
> User.create(name:"user1")
> User.first
#<User id: 1, name: "user1", address_id: 1, created_at: "2013-12-14 11:52:38", updated_at: "2013-12-14 11:52:38">
編集 履歴 (0)
  • ご回答ありがとうございます。しかしそれでは上手くいきませんでした。追記をしたのでもしよろしければご拝見ください。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。