2009-09-10 3 views
7

다음과 같은 연관이 있습니다. 기본적으로 개체 ID가 아니라 사용자 ID를 통해 링크하고 싶습니다.레일스 - 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

은 'personA'입니까? – ErsatzRyan

+0

이렇게 전달됩니다. 그렇습니다 :

 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

userid를 외래 키로 사용해야하는 이유가 있습니까? 연관된 필드의 기본 키를 사용하지 않는 것이 좋습니다. – jonnii

답변

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

감사하지만 내 ID는 ID입니다. 그러나이 연관성을 위해 다른 열을 사용하고 싶습니다. –

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 클래스는 현재 컨트롤러 또는 모두 동작에만 영향을 미칩니다. 아직도, 그것은 단지 내가 해결 방법으로 생각하는 것입니다.

1

두 가지가 있습니다. 나는 has_one 및 : belongs_to 선언을 전환했다고 생각한다.

:belongs_to은 외래 키가있는 모델입니다. :has_one은 언급 된 모델에 포함되어 있습니다 (단 하나 인 경우 많은 행이 동일한 경우 belongs_to는 당연히 has_many입니다). 자세한 내용은 here을 참조하십시오.

먼저 모델의 기본 키를 지정해야합니다 (overrule). 여기에서는 사용자가 단지 하나 대신 많은 트윗을 가질 수 있다고 가정합니다 (그렇지 않으면 :has_one으로 바꿉니다).

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

당신의 관계가 올바르게 설정을 일단 다음, 둘째, 작성시 :user_profile 또는 :userid 모두를 할당 할 필요가 없습니다 :

class UserProfile 
    set_primary_key :userid 
    has_many :tweets 
end 

는 당신은 당신 :has_one 선언을 조정해야합니다. 새 UserProfile을 만들고 외부 키가 자동으로 올바르게 입력되거나 userid 기존 프로필을 할당합니다.

희망이 도움이됩니다.