1

has_many/belongs_to 関係を介して関連付けられた Trainer モデルと Client モデルを作成しました。Trainer has_many Clients と Client belongs_to Trainer。ただし、 を使用して既存のクライアントを既存のトレーナーに追加しようとするTrainer.Clients << Clientと、データベースに保存されません。

クライアント モデル:

class Client < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation, :trainer_id
  has_secure_password
  belongs_to :trainer

  validates :name, presence: true, length: { maximum: 40 }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true, length: { minimum: 6 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }

  before_save { |client| client.email = email.downcase }
end

トレーナー モデル:

class Trainer < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  has_many :clients

  validates :name, presence: true
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, 
                                                                    uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true, length: { minimum: 6 }

  before_save { |trainer| trainer.email = email.downcase } 
end

データベースの Client テーブルには、trainer_id のforeign_id があります。

create_table "clients", :force => true do |t|
  t.string   "name"
  t.string   "email"
  t.datetime "created_at",      :null => false
  t.datetime "updated_at",      :null => false
  t.string   "password_digest"
  t.integer  "trainer_id"
end

コンソールでクライアント レコードをトレーナーに追加しようとすると、データベースへの保存に失敗します。

1.9.3-p194 :001 > trainer = Trainer.find(2)
  Trainer Load (30.1ms)  SELECT "trainers".* FROM "trainers" WHERE "trainers"."id" = ? LIMIT 1  [["id", 2]]
 => #<Trainer id: 2, name: "Noah Macejkovic", email: "trainer-1@mp-trainer.com", created_at: "2012-06-06 20:40:45", updated_at: "2012-06-06 20:40:45", password_digest: "$2a$10$bDL0ealWYdsxpN2jOyToCO9T/WKsI4I7WXdhRXQBvcP1..."> 

1.9.3-p194 :002 > client = Client.find(2)
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", 2]]
 => #<Client id: 2, name: "Katherine Skiles V", email: "client-1@example.com", created_at: "2012-06-06 20:40:54", updated_at: "2012-06-06 20:40:54", password_digest: "$2a$10$47CUSOS3k5j1c.DjH2PP7uqHD6kM94rZHMco37X34li/...", trainer_id: nil> 

1.9.3-p194 :003 > trainer.clients << client
   (0.1ms)  begin transaction
  Client Exists (0.4ms)  SELECT 1 FROM "clients" WHERE (LOWER("clients"."email") = LOWER('client-1@example.com') AND "clients"."id" != 2) LIMIT 1
   (0.1ms)  commit transaction
 => false 

トランザクションの直後にクライアントにクエリを実行すると、trainer_id が表示されます

1.9.3-p194 :004 > client
 => #<Client id: 2, name: "Katherine Skiles V", email: "client-1@example.com", created_at: "2012-06-06 20:40:54", updated_at: "2012-06-06 20:40:54", password_digest: "$2a$10$47CUSOS3k5j1c.DjH2PP7uqHD6kM94rZHMco37X34li/...", trainer_id: 2> 

しかし、データベースからリロードした後、trainer_id は nil です ( trainer.clients << client.

1.9.3-p194 :006 > client.reload
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", 2]]
 => #<Client id: 2, name: "Katherine Skiles V", email: "client-1@example.com", created_at: "2012-06-06 20:40:54", updated_at: "2012-06-06 20:40:54", password_digest: "$2a$10$47CUSOS3k5j1c.DjH2PP7uqHD6kM94rZHMco37X34li/...", trainer_id: nil>

したがって、問題の核心は、「データベースへのコミットが失敗するのはなぜですか?」ということです。

4

0 に答える 0