我有以下关联,基本上我想通过userid链接而不是对象的id。
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'
然而,以下规范失败,因为twitter_userid被重置为对象的id
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
应该在用户个人资料中设置用户的Twitter ID
expected: "personA",
got: 216 (using ==)
但是,以下内容确实通过了:
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
如何强制它使用userid而不是id?
由于
本
答案 0 :(得分:1)
cite@antiope:/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
如果您只需要在一个地方重新定义主键,那么在保存模型之前一段时间修改模型可能是一个可接受的解决方案(我没有测试修改Tweet
类是否只影响当前控制器或所有操作)。不过,这只是我认为的解决方法。
答案 1 :(得分:1)
这里有两件事。我想你已经切换了:has_one和:belongs_to声明。
:belongs_to
出现在具有外键的模型中。
:has_one
出现在所引用的模型中(如果它只有一个,否则如果有很多行:belongs_to相同,当然它是has_many)。有关详细信息,请阅读here。
首先,您需要指定(否决)模型的主键。在这里,我假设一个用户可以有很多推文,而不只是一个(否则由:has_one
替换。)
class UserProfile
set_primary_key :userid
has_many :tweets
end
然后您需要调整:has_one
声明:
class Tweet
belongs_to :user_profile, :foreign_key => :userid
end
然后,其次,一旦您的关系设置正确,就无需在创建时分配:user_profile
或:userid
。您可以创建新的UserProfile
,并且外键会自动更正,或者您分配现有个人资料的userid
。
希望这有帮助。
答案 2 :(得分:0)
如果数据库中的主键未被称为id,那么您希望执行以下操作:
class Tweet < AR:B
set_primary_key "userid"
end
但是,我不确定我完全理解这个问题。您是否有理由想要超越铁路惯例?
答案 3 :(得分:0)
我认为这可能是最实用的方法。我认为在Rails中不可能: http://compositekeys.rubyforge.org/