3

让我们假设 User 和 Company 模型之间有一个通用连接表 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:

路线.rb:

resources :follow_companies

然而,这会导致一个问题:这些生成的路由假设一个我没有的 :id 键。我如何告诉 rails 我实际上使用的是复合键?

我可以想到四种解决方案,我想就哪一种最好提供一些意见:

  1. 不要使 :follow_companies 成为资源。取而代之的是,将 URL 与两个关键模式匹配:例如:match '/follow_companies/:user_id/:company_id/' => follow_companies#edit 这很丑,因为它很冗长而不是 RESTful。

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

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

    然而,这很丑陋,因为它看起来像一个 hack 并且它有一些令人讨厌的副作用

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

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

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

4

2 回答 2

2

数字 3 的优点是您的密钥将毫无意义。虽然不适用于您的情况,但如果某个键值由于某种原因需要更改,则使用复合键会导致该资源的 URL 发生更改。创建一个无意义的主键意味着即使数据发生变化,URL 也会保持不变。

这也往往是执行连接表的“Rails 方式”。

于 2013-03-22T22:12:34.087 回答
0

我对 ActiveRecord 没有那么自信,但为什么要使用组合键?当然,您所描述的是 many_to_many 连接。那么这行不通:

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

或类似的东西?

于 2013-03-22T22:02:45.243 回答