【问题标题】:rails 3 has_and_belongs_to_manyrails 3 has_and_belongs_to_many
【发布时间】:2012-01-14 11:55:33
【问题描述】:

我有一个旧数据库。用户有很多账户,账户有很多用户。有一个名为 UserAccountMapping 的连接表:

=====================
|UserID  | AccountID|
=====================

两列都是 var chars 类型。

在 Account.rb 中:

has_and_belongs_to_many :users, :join_table => :UserAccountMapping, :foreign_key => :AccountID, :association_foreign_key => :UserID

在 User.rb 中:

has_and_belongs_to_many :accounts, :join_table => 'UserAccountMapping', :foreign_key => :UserID, :association_foreign_key => :AccountID

用户还有一个 :email 和 :id 列。用户的主键是 :id (整数), :email 是字符串。

当我执行User.first.accounts 之类的操作时,连接 SQL 的 WHERE 子句将尝试将 UserAccountMapping.UserID 与用户的 :id 匹配,但我希望它使用用户的 :email。这可能吗?

所以,它生成的 SQL 是:

SELECT "Account".* FROM "Account" INNER JOIN "UserAccountMapping" ON "Account"."AccountID" = "UserAccountMapping"."AccountID" WHERE "UserAccountMapping"."UserID" = 3

相反,我想要这个:

SELECT "Account".* FROM "Account" INNER JOIN "UserAccountMapping" ON "Account"."AccountID" = "UserAccountMapping"."AccountID" WHERE "UserAccountMapping"."UserID" = "user@something.com"

【问题讨论】:

  • 您为什么要这样做?尝试设置 User 主键 => :email

标签: ruby-on-rails ruby


【解决方案1】:

您在此处构建数据的方式非常不符合 Rails,以至于您必须努力让它发挥作用。这就是约定俗成的问题。如果你违反规定,实施起来会非常困难。

使用UserID 等非标准列名而不是user_id 会在您的应用程序中产生大量复杂性。如果可能的话,切换到 Rails 风格,省去你必须覆盖所有东西的麻烦。

您还应该避免使用has_and_belongs_to_many,因为它是Rails 1 的遗物,不如Rails 2+ 中的has_many :through 功能有用。您只需要连接表中的 id 主键列和设置两个 belongs_to 关系的关联模型文件。

使用非标准的id 列也会造成麻烦,只能作为最后的手段。大多数情况下,您可以使用该列上的UNIQUE 索引及其查找方法来解决此问题:

@user = User.find_by_email(email)
@account = @user && @user.accounts.first

如果您遵循“Rails 方式”,事情会变得更好。学习 Rails 的一个重要部分是知道什么时候一起玩,什么时候以及如何打破常规,走自己的路而不会惹上麻烦。

【讨论】:

  • 不幸的是,它是一个遗留数据库,所以我无法更改列名以遵循 Rails 约定。我也尝试过has_many :through 功能,但我也遇到了同样的问题。
  • 所以,你应该考虑不使用 Rails,因为它对你来说会非常困难和复杂 :(.
  • 如果您真的很困难,您可能想尝试使用Sequel ORM 而不是 ActiveRecord。它往往更加灵活,因为它不会做出太多假设并且可以处理非常规的键控安排。
猜你喜欢
  • 2011-09-30
  • 1970-01-01
  • 2010-10-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
相关资源
最近更新 更多