ruby-on-rails - Rails has_many 通过具有命名空间模型的多态

标签 ruby-on-rails ruby namespaces has-many-through polymorphic-associations

我的类(class)和迁移如下。不确定我做错了什么,是我设置了错误的关联还是我没有使用正确的属性/方法来返回我期望的记录。例如,我如何获取 super_admin_users 的所有成员的列表( admin_usersstandard_users account ) ?在 Rails 控制台中,如果我尝试 Accounts::Account.first.users_account_members ,我得到以下信息:

2.4.0 :003 > Accounts::Account.first.users_account_members
Accounts::Account Load (0.6ms)  SELECT  "accounts_accounts".* FROM "accounts_accounts" ORDER BY "accounts_accounts"."id" ASC LIMIT $1  [["LIMIT", 1]]
NoMethodError: undefined method `users_account_members' for #<Accounts::Account:0x007fcb10cce7b8>

如果我尝试 Accounts::Account.first.users_super_admin_users ,我得到以下信息:
2.4.0 :004 > Accounts::Account.first.users_super_admin_users
Accounts::Account Load (0.6ms)  SELECT  "accounts_accounts".* FROM "accounts_accounts" ORDER BY "accounts_accounts"."id" ASC LIMIT $1  [["LIMIT", 1]]
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column accounts_account_memberships.accounts_account_type does not exist

其中,通过寻找accounts_account_memberships.accounts_account_type ,它似乎表现得好像 accounts_account当只有用户方是多态时,关联方是多态的。

此外,相反,我如何获得所有 accounts 的列表一个特定的 super_admin_user (或 admin_userstandard_user )是成员?

这是我的带有关联的类及其迁移:

app/models/accounts/account.rb
module Accounts
  class Account < ActiveRecord::Base

    self.table_name = 'accounts_accounts'

    belongs_to :users_account_owner, class_name: 'Users::SuperAdminUser', inverse_of: :accounts_owned_accounts
    accepts_nested_attributes_for :users_account_owner

    has_many :accounts_account_memberships, class_name: 'Accounts::AccountMembership', as: :accounts_account, dependent: :destroy
    has_many :users_super_admin_users, through: :accounts_account_memberships, source: :users_account_member, source_type: 'Users::SuperAdminUser'
    has_many :users_admin_users,       through: :accounts_account_memberships, source: :users_account_member, source_type: 'Users::AdminUser'
    has_many :users_standard_users,    through: :accounts_account_memberships, source: :users_account_member, source_type: 'Users::StandardUser'

  end
end

应用程序/模型/用户/super_admin_user.rb
module Users
  class SuperAdminUser < ApplicationRecord

    self.table_name = 'users_super_admin_users'

    has_many :accounts_owned_accounts, class_name: 'Accounts::Account', inverse_of: :users_account_owner, foreign_key: :users_account_owner_id

    has_many :accounts_account_memberships, class_name: 'Accounts::AccountMembership', as: :users_account_member, dependent: :destroy
    has_many :accounts_accounts, through: :accounts_account_memberships, source: 'Accounts::Account'

  end
end

应用程序/模型/用户/admin_user.rb
module Users
  class AdminUser < ApplicationRecord

    self.table_name = 'users_admin_users'

    has_many :accounts_account_memberships, class_name: 'Accounts::AccountMembership', as: :users_account_member, dependent: :destroy
    has_many :accounts_accounts, through: :accounts_account_memberships, source: 'Accounts::Account'

  end
end

应用程序/模型/用户/standard_user.rb
module Users
  class StandardUser < ApplicationRecord

    self.table_name = 'users_standard_users'

    has_many :accounts_account_memberships, class_name: 'Accounts::AccountMembership', as: :users_account_member, dependent: :destroy
    has_many :accounts_accounts, through: :accounts_account_memberships, source: 'Accounts::Account'

  end
end

app/models/accounts/account_membership.rb
module Accounts
  class AccountMembership < ActiveRecord::Base

    self.table_name = 'accounts_account_memberships'

    belongs_to :accounts_account, class_name: 'Accounts::Account', inverse_of: :accounts_account_memberships
    belongs_to :users_account_member, polymorphic: true

  end
end

db/migrate/20170203001000_create_users_super_admin_user.rb
class CreateUsersSuperAdminUser < ActiveRecord::Migration[5.0]
  def change
    create_table :users_super_admin_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

db/migrate/20170203001100_create_users_admin_user.rb
class CreateUsersAdminUser < ActiveRecord::Migration[5.0]
  def change
    create_table :users_admin_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

db/migrate/20170203001200_create_users_standard_user.rb
class CreateUsersStandardUser < ActiveRecord::Migration[5.0]
  def change
    create_table :users_standard_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

db/migrate/20170204001000_create_accounts_account.rb
class CreateAccountsAccount < ActiveRecord::Migration[5.0]
  def change
    create_table :accounts_accounts do |t|

      t.string :name, index: { unique: true }

      t.references :users_account_owner, index: true, foreign_key: { to_table: :users_super_admin_users }

      t.timestamps null: false

    end
  end
end

db/migrate/20170204001100_create_accounts_account_membership.rb
class CreateAccountsAccountMembership < ActiveRecord::Migration[5.0]
  def change
    create_table :accounts_account_memberships do |t|

      t.references :accounts_account, index: { name: 'index_accts_acct_mbrships_on_accts_acct_id' }
      t.references :users_account_member, polymorphic: true, index: { name: 'index_accts_acct_mbrships_on_users_acct_member_type_and_id' }

      t.timestamps null: false

    end
  end
end

最佳答案

要使用这种多态关联,您必须在 中声明一个类型列。帐号成员(member)模型。

像这样:

class AddAccountsAccountTypeToAccountsAccountMemberships < ActiveRecord::Migration[5.0]
  def change
    add_column :accounts_account_memberships, :accounts_account_type, :string
  end
end

如果我理解正确,要获得所有成员的列表,您必须使用 Accounts::Account.first.accounts_account_memberships而不是 Accounts::Account.first.users_account_members
并获取所有 accounts 的列表一个特定的 standard_user你应该调用 Users::StandardUser.first.accounts_accounts

关于ruby-on-rails - Rails has_many 通过具有命名空间模型的多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42173090/

相关文章:

ruby-on-rails - 销毁前验证

ruby-on-rails - 无法在任何来源中找到 json-1.8.1 (Bundler::GemNotFound)

ruby - 按 Ruby 中的修改日期对文件路径列表进行排序

ruby-on-rails - Hpricot CSS 类搜索

ruby - "\n"和 '\n' 的长度

ruby-on-rails - 通过rvm安装后找不到Rails

ruby-on-rails - 按权限过滤后的 rails 4 activerecord 关系分页

.net - 如何在没有 xmlns ="..."的情况下到处使用 XML 命名空间前缀? (。网)

linux - 在 linux 内核模块中获取全局网络命名空间的实例

namespaces - 在控制台 C++ 应用程序中使用 WIndows::System::Launcher 类成员函数的 C++ 示例