假设用户和公司模型之间存在通用联接表FollowCompany,例如:
class FollowCompany < ActiveRecord::Base
attr_accessible :user_id, :company_id
belongs_to :user
belongs_to :company
end
它有一个复合主键[user_id,company_id]。 它没有id列,因为follow_company记录由[used_id,company_id]唯一标识
由于我希望能够将以下关系视为资源,因此我将其设为RESTful:
routes.rb中:
resources :follow_companies
然而这会导致一个问题:这些生成的路由假设一个我没有的id键。 我如何告诉rails我实际上使用的是复合键?
我可以想到四种解决方案,我想要一些最好的输入:
不要:跟随一个资源。相反,将网址与两个关键模式匹配:例如:match '/follow_companies/:user_id/:company_id/' => follow_companies#edit
然而,这很难看,因为它很冗长,而不是RESTful。
重写FollowCompany to_param方法以包含两个模型ID,例如
def to_param
"#{user_id},#{company_id}"
end
然而这很难看,因为它看起来像是一个黑客,它有一些令人讨厌的副作用
将一个主键列添加到follow_company表中。 然而,这很难看,因为它增加了冗余。 follow_company记录由[company_id,user_id]唯一标识。无需额外的钥匙。
下载复合键宝石并将其与我的开发环境集成。 然而,这很难看,因为它不是标准方式,与其他ruby代码不兼容。
所以,正如你所看到的,我无法想出一个优雅的解决方案。 这似乎是一种常见的情况,尽管我不能成为第一个遇到这种情况的人。实际上每个应用程序都使用(restful)连接表。 处理此问题的最佳做法是什么?
答案 0 :(得分:2)
3号的优点是你的密钥没有意义。虽然不适用于您的情况,但如果由于某种原因需要更改其中一个键值,则使用复合键会导致该资源的URL发生更改。创建无意义的主键意味着即使数据发生更改,URL也会保持不变。
这也往往是做连接表的“Rails方式”。
答案 1 :(得分:0)
我对ActiveRecord没有那么自信,但为什么要使用组合密钥呢?当然,你所描述的是多次加入。所以这不起作用:
class User < ActiveRecord::Base
has_many :follow_companies
has_many :companies, through: :follow_companies
end
class FollowCompany < ActiveRecord::Base
belongs_to :user
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :follow_companies
end
这意味着您可以直接路由到公司作为嵌套路线,如下所示:
resources :users do
collection :follow_companies
end
这会为您提供“/ users / 1 / follow_companies”等路线,并且您可以在控制器中执行以下操作:
class UsersController < ApplicationController
def follow_companies
@user = User.find(params[:id])
@companies = @user.companies
end
end
或类似的东西?