2010-04-20 26 views
8

Trong đường ray, khi lưu đối tượng active_record, các đối tượng liên quan của nó cũng sẽ được lưu. Nhưng has_one và has_many hiệp hội có thứ tự khác nhau trong việc lưu các đối tượng.Lưu một bản ghi hoạt động, theo thứ tự các đối tượng liên kết được lưu là gì?

Tôi có ba mô hình đơn giản:

class Team < ActiveRecord::Base 
    has_many :players 
    has_one :coach 
end 

class Player < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

class Coach < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

tôi mong đợi rằng khi team.save được gọi, đội nên được lưu trước khi HLV và các cầu thủ liên quan của nó.

tôi sử dụng đoạn mã sau để kiểm tra các mô hình:

t = Team.new 
team.coach = Coach.new 
team.save! 

team.save! trả về true.

Nhưng trong thử nghiệm khác:

t = Team.new 
team.players << Player.new 
team.save! 

team.save! cung cấp cho các lỗi sau:

> ActiveRecord::RecordInvalid: 
> Validation failed: Players is invalid 

tôi đã tìm ra rằng team.save! tiết kiệm đối tượng theo thứ tự sau: 1) người chơi, 2) đội bóng, và 3) huấn luyện viên. Đây là lý do tại sao tôi nhận được lỗi: Khi một người chơi được lưu, đội bóng chưa có id, do đó, validates_presence_of :team_id không thành công trong trình phát.

Ai đó có thể giải thích cho tôi tại sao các đối tượng được lưu theo thứ tự này không? Điều này có vẻ không hợp lý với tôi.

+0

Để làm cho vấn đề rõ ràng hơn: khi team.save! được gọi là, có thể để đối tượng nhóm được lưu vào cơ sở dữ liệu trước đối tượng trình phát không? – Shuo

Trả lời

0

Bạn nên sử dụng "validates_associated" để thực hiện điều đó

séc Here

Cái gì đó như sau không kiểm tra mặc dù

class Team < ActiveRecord::Base 
    has_many :players 
    has_one :coach 
    validates_associated :players, :coach ###MOST IMPORTANT LINE 
end 

class Player < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

class Coach < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

Trong điều khiển của bạn

t = Team.new 

@coach = t.build_coach(:column1=> "value1", :column2=> "value2") # This create new object with @coach.team_id= t.id 
@players = t.players.build 

t.save#This will be true it passes the validation for all i.e. Team, COach & Player also save all at once otherwise none of them will get saved. 
+2

Điều này vẫn làm tăng ActiveRecord :: RecordInvalid. – zetetic

+0

hãy đặt mã của bạn với "validates_associated" – Salil

+0

validates_associated chỉ xác nhận rằng mô hình được liên kết hợp lệ trong chính nó, nhưng không xác thực rằng mô hình được liên kết có mặt. Đối với điều đó, bạn cần validates_presence_of. Xem http://github.com/rails/rails/blob/v3.0.0.beta.3/activerecord/lib/active_record/validations/associated.rb để biết chi tiết đầy đủ. –

-1

Hãy xem xét của bạn kiểm tra không thành công:

t = Team.new 
team.players << Player.new 
team.save! 

Thêm một cầu thủ mới để hiệp hội team.players cố gắng để thiết lập team_id vào chơi ngay trên dòng 2. Đó chỉ là cách < < công trình nhà điều hành. Nó không được cập nhật khi bạn lưu nhóm, vì vậy ngay cả khi đội được lưu trước, người chơi vẫn có một team_id trống. Trong trường hợp này, bạn có thể dễ dàng giải quyết nó bằng cách hoán đổi các dòng 2 và 3.

Các vấn đề liên quan