2009-09-10 24 views
7

Tôi có các liên kết sau, về cơ bản tôi muốn liên kết qua userid chứ không phải id của đối tượng.Đường ray - Ghi đè khóa chính trên has_one

class Tweet < ActiveRecord::Base 
    has_one :user_profile, :primary_key => 'userid', :foreign_key => 'twitter_userid'

 
class UserProfile < ActiveRecord::Base 
    belongs_to :tweet, :foreign_key => 'userid'

However the following spec fails as twitter_userid is reset to the id of the object

 
it "should have the user's twitter id set on their user profile" do 
    t = Tweet.new(:twitter_id => 1, 
        :status => 'Tester', 
        :userid => 'personA', 
        :user_profile => UserProfile.new(:twitter_userid => 'personA', :avatar => 'abc')) 
    t.save! 
    t.user_profile.twitter_userid.should == 'personA' 
end 

should have the user's twitter id set on their user profile

expected: "personA", 
    got: 216 (using ==)

However, the following does pass:

 
it "should return the correct avatar after being saved" do 
    t = Tweet.new(:twitter_id => 1, 
        :status => 'Tester', 
        :userid => 'personA', 
        :user_profile => UserProfile.new(:twitter_userid => 'personA', :avatar => 'abc')) 
    t.save! 

    t.user_profile.avatar.should == 'abc' 
end 

How can I force it to use userid and not id?

Thanks

Ben

+0

là 'personA' sẽ chuyển vào db của bạn? – ErsatzRyan

+0

Điều này xảy ra, do đó, có nó là:

 it "should save" do t = Tweet.new(:twitter_id => 1, :status => 'Tester', :userid => 'personA', :user_profile => UserProfile.new(:twitter_userid => 'personA', :avatar => 'abc')) t.save! t.userid.should == 'personA' t.new_record?.should == false t.valid?.should == true t.user_profile.new_record?.should == false t.user_profile.valid?.should == true end 

+0

Có lý do nào khiến bạn cần sử dụng userid làm khóa ngoại không? Tại sao không chỉ sử dụng khóa chính của trường được liên kết. – jonnii

Trả lời

0

If the primary key on your db is not called id then you want to do something like this:

class Tweet < AR:B 
    set_primary_key "userid" 
end 

However, I'm not sure I totally understand the question. Is there a reason you want to step outside of the rails conventions?

+0

cảm ơn, nhưng ID của tôi là id. Tuy nhiên, đối với hiệp hội này, tôi muốn sử dụng một cột khác –

1
[email protected]:/tmp/foo$ script/console 
Loading development environment (Rails 2.3.4) 
>> t = Tweet.new(:twitter_id => 1, 
?>     :status => 'Tester', 
?>     :userid => 'personA', 
?>     :user_profile => UserProfile.new(:twitter_userid => 'personA', :avatar => 'abc')) 
=> #<Tweet id: nil, twitter_id: 1, status: "Tester", userid: "personA", created_at: nil, updated_at: nil> 
>> Tweet.set_primary_key :userid 
=> nil 
>> t.save 
    Tweet Create (0.4ms) INSERT INTO "tweets" ("created_at", "updated_at", "userid", "twitter_id", "status") VALUES('2009-09-10 20:19:36', '2009-09-10 20:19:36', 'personA', 1, 'Tester') 
    UserProfile Create (0.1ms) INSERT INTO "user_profiles" ("twitter_userid", "created_at", "updated_at", "avatar") VALUES('personA', '2009-09-10 20:19:36', '2009-09-10 20:19:36', 'abc') 
=> true 
>> Tweet.set_primary_key :id 
=> nil 

Modfiying the model a split second before saving it might be an acceptable solution if you only have to redefine the primary key in one place (I didn't test if modifying the Tweet lớp như vậy chỉ ảnh hưởng đến bộ điều khiển hiện tại hoặc tất cả hành động). Tuy nhiên, nó chỉ là những gì tôi coi là một cách giải quyết.

1

Có hai điều đang diễn ra ở đây. Tôi nghĩ bạn đã chuyển đổi: has_one và: declare_to declarationations.

:belongs_to có trong mô hình có khóa ngoài. Các :has_one đi kèm trong mô hình được gọi (nếu nó chỉ là một, nếu không nếu nhiều hàng: thuộc về cùng một, nó là một has_many tất nhiên). Để biết thêm thông tin, hãy đọc here.

Trước tiên, bạn sẽ cần chỉ định (ghi đè) khóa chính của mô hình. Ở đây tôi giả sử một người dùng có thể có nhiều tweet thay vì chỉ một (nếu không thay thế bằng :has_one).

class UserProfile 
    set_primary_key :userid 
    has_many :tweets 
end 

sau đó bạn cần phải điều chỉnh :has_one khai của bạn:

class Tweet 
    belongs_to :user_profile, :foreign_key => :userid 
end 

Sau đó, thứ hai, một khi mối quan hệ của bạn được thiết lập một cách chính xác, không có cần phải gán cả :user_profile hoặc :userid lúc sáng tạo. Hoặc bạn tạo UserProfile mới và các khóa ngoại sẽ tự động theo đúng hoặc bạn chỉ định userid của cấu hình hiện có.

Hy vọng điều này sẽ hữu ích.

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