【问题标题】:Many-To-Many with custom model names in Rails 4在 Rails 4 中具有自定义模型名称的多对多
【发布时间】:2017-02-13 04:42:51
【问题描述】:

在我的 Rails 4 应用程序中,我有用户和帐户。我想通过关系创建一个 has_many 。事情是我想更改班级名称,以便一个帐户有许多用户类型的经理。另一方面,该帐户有许多托管(类型帐户)

所以我有我的直通表:

class AccountManager < ActiveRecord::Base
  belongs_to :account, class_name: 'Managed'
  belongs_to :user, class_name: 'Manager'
end

在我的帐户模型中,我有:

has_many :account_managers
has_many :managers, :through => :account_managers, :source => :user

但是当我做Account.first.managers 时,我得到:

未初始化的常量 Account::Manager

我忘记了什么?

【问题讨论】:

  • 你能发布你的经理课程吗?
  • Manager 类不存在。这是 User 类,但我想在我的关系中称它为 Manager ......我不知道这是否清楚。
  • 在这种情况下AccountManger.first.user 也不起作用。您编写的belongs_to 关系将Manager 指定为class_name。你应该写belongs_to :mangers, class_name: 'User',foreign_key: :(user/manager)_id

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

我让它使用 User 的自定义名称,但是当我为 Account 添加自定义名称时,它一直在寻找 type,它应该只在它是多态的。我无法解决这个问题,我最终找到了这个,这似乎完全按照我认为你需要的方式工作(查看底部的 Nic 的解决方案,而不是接受的答案):

has_many :through with class_name and foreign_key

根据该答案,如果您的模型和迁移如下所示,它应该可以工作:

class Account < ActiveRecord::Base
  has_many :manager_account_pairs
  has_many :account_managers, through: :manager_account_pairs, source: :user
end

class User < ActiveRecord::Base
  has_many :manager_account_pairs
  has_many :managed_accounts, through: :manager_account_pairs, source: :account
end

class ManagerAccountPair < ActiveRecord::Base
  belongs_to :account
  belongs_to :user
end

class CreateAccount < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.string :name, index: { unique: true }
      t.timestamps null: false
    end
  end
end

class CreateUser < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :email, index: { unique: true }
      t.string :first_name
      t.string :last_name
      t.string :username, index: { unique: true }
      t.timestamps null: false
    end
  end
end

class CreateManagerAccountPair < ActiveRecord::Migration
  def change
    create_table :manager_account_pairs do |t|
      t.integer :account_id
      t.integer :user_id
      t.timestamps null: false
    end
  end
end

这是一个用于测试的种子文件:

User.create(email: 'lhawkinsa@icio.us',            first_name: 'Lisa',    last_name: 'Hawkins',  username: 'lhawkinsa')
User.create(email: 'htaylorb@imdb.com',            first_name: 'Helen',   last_name: 'Taylor',   username: 'htaylorb')
User.create(email: 'gtaylorc@unblog.fr',           first_name: 'Gregory', last_name: 'Taylor',   username: 'gtaylorc')
User.create(email: 'hlaned@whitehouse.gov',        first_name: 'Henry',   last_name: 'Lane',     username: 'hlaned')
User.create(email: 'hphillipse@howstuffworks.com', first_name: 'Harry',   last_name: 'Phillips', username: 'hphillipse')
User.create(email: 'jgonzalesf@com.com',           first_name: 'Jeffrey', last_name: 'Gonzales', username: 'jgonzalesf')
User.create(email: 'ljamesg@sfgate.com',           first_name: 'Lori',    last_name: 'James',    username: 'ljamesg')
User.create(email: 'rhillh@gnu.org',               first_name: 'Roger',   last_name: 'Hill',     username: 'rhillh')
User.create(email: 'rharveyi@tripadvisor.com',     first_name: 'Raymond', last_name: 'Harvey',   username: 'rharveyi')
User.create(email: 'sperryj@mit.edu',              first_name: 'Stephen', last_name: 'Perry',    username: 'sperryj')

Account.create(name: 'Ooba')
Account.create(name: 'Avamba')
Account.create(name: 'Linktype')
Account.create(name: 'Brainsphere')
Account.create(name: 'Wordtune')

ManagerAccountPair.create(account_id: 1, user_id: 1)
ManagerAccountPair.create(account_id: 2, user_id: 2)
ManagerAccountPair.create(account_id: 3, user_id: 3)
ManagerAccountPair.create(account_id: 4, user_id: 4)
ManagerAccountPair.create(account_id: 5, user_id: 5)
ManagerAccountPair.create(account_id: 1, user_id: 6)
ManagerAccountPair.create(account_id: 2, user_id: 7)
ManagerAccountPair.create(account_id: 3, user_id: 8)
ManagerAccountPair.create(account_id: 4, user_id: 9)
ManagerAccountPair.create(account_id: 5, user_id: 10)

控制台输出:

~/workspace/rails_four_example>> rails c
Running via Spring preloader in process 8465
Loading development environment (Rails 4.2.7.1)

    2.3.3 :001 > Account.first.account_managers
Account Load (1.2ms)  SELECT  "accounts".* FROM "accounts"  ORDER BY "accounts"."id" ASC LIMIT 1
User Load (0.8ms)  SELECT "users".* FROM "users" INNER JOIN "manager_account_pairs" ON "users"."id" = "manager_account_pairs"."user_id" WHERE "manager_account_pairs"."account_id" = $1  [["account_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1, email: "lhawkinsa@icio.us", first_name: "Lisa", last_name: "Hawkins", username: "lhawkinsa", created_at: "2017-02-12 19:58:42", updated_at: "2017-02-12 19:58:42">, #<User id: 6, email: "jgonzalesf@com.com", first_name: "Jeffrey", last_name: "Gonzales", username: "jgonzalesf", created_at: "2017-02-12 19:58:42", updated_at: "2017-02-12 19:58:42">]> 

    2.3.3 :002 > User.first.managed_accounts
User Load (0.8ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
Account Load (0.5ms)  SELECT "accounts".* FROM "accounts" INNER JOIN "manager_account_pairs" ON "accounts"."id" = "manager_account_pairs"."account_id" WHERE "manager_account_pairs"."user_id" = $1  [["user_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Account id: 1, name: "Ooba", created_at: "2017-02-12 19:58:42", updated_at: "2017-02-12 19:58:42">]> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    相关资源
    最近更新 更多