使用rails中的复合键连接表

时间:2013-03-22 21:14:15

标签: ruby-on-rails routes composite-primary-key jointable

假设用户和公司模型之间存在通用联接表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我实际上使用的是复合键?

我可以想到四种解决方案,我想要一些最好的输入:

  1. 不要:跟随一个资源。相反,将网址与两个关键模式匹配:例如:match '/follow_companies/:user_id/:company_id/' => follow_companies#edit 然而,这很难看,因为它很冗长,而不是RESTful。

  2. 重写FollowCompany to_param方法以包含两个模型ID,例如

    def to_param
     "#{user_id},#{company_id}"
    end
    

    然而这很难看,因为它看起来像是一个黑客,它有一些令人讨厌的副作用

  3. 将一个主键列添加到follow_company表中。 然而,这很难看,因为它增加了冗余。 follow_company记录由[company_id,user_id]唯一标识。无需额外的钥匙。

  4. 下载复合键宝石并将其与我的开发环境集成。 然而,这很难看,因为它不是标准方式,与其他ruby代码不兼容。

  5. 所以,正如你所看到的,我无法想出一个优雅的解决方案。 这似乎是一种常见的情况,尽管我不能成为第一个遇到这种情况的人。实际上每个应用程序都使用(restful)连接表。 处理此问题的最佳做法是什么?

2 个答案:

答案 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

或类似的东西?