0

ユーザーと企業向けの基本的な has_many through: を取得しました。

class User < ActiveRecord::Base
  extends CompanyMethods
  has_many :company_users
  has_many :companies, through: company_users

  has_many :orders
end

class CompanyUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :company
  validates_uniqueness_of :company_id, scope: :user_id
end

class Company < ActiveRecord::Base
  has_many :company_users
  has_many :users, through: company_users
end

次に、ユーザーCompanyMethodsに a を追加するこの lib があります。default_scope

module CompanyMethods
  def self.extended(klass)
    klass.class_eval do
      default_scope do
        c_ids = Authorization.current_company_ids
        includes(:companies).where(companies: { id: c_ids })
      end
    end
  end
end

したがって、 を呼び出すUser.find_by_email('michael@widgetworks.com')と、 によってスコープが設定されたユーザーのみが返されAuthorization.current_company_idsます。

SQLは次のとおりです。

SELECT DISTINCT `users`.id FROM `users` LEFT OUTER JOIN `company_users` ON `company_users`.`user_id` = `users`.`id` LEFT OUTER JOIN `companies` ON `companies`.`id` = `company_users`.`company_id` WHERE `companies`.`id` IN (4) AND `users`.`email` = 'michael@widgetworks.com' LIMIT 1

多くの場合、これはすべてうまくいきます。しかし、ここからファンキーになり始めます。

別のオブジェクト、たとえば CreditCard が User を通過するアソシエーションを呼び出すとcompanies.id、子オブジェクトでスコープが呼び出されます。

class CreditCard < ActiveRecord::Base
  has_one :user, through: :user_profile
  has_many :orders, through: :user
end

class UserProfile < ActiveRecord::Base
  belongs_to :user
end

生成される sql は次のとおりです。

SELECT `orders`.* FROM `orders` INNER JOIN `users` ON `orders`.`user_id` = `users`.`id` INNER JOIN `user_profiles` ON `users`.`id` = `user_profiles`.`user_id` WHERE `orders`.`company_id` IN (4) AND `companies`.`id` IN (4) AND `user_profiles`.`id` = 47717

credit_card.ordersSQL クエリが " companies. idIN (4)" を呼び出しreservationているため、エラーをスローしますuser

throughアソシエーションを使用する代わりにreservations、CreditCardという名前のメソッドを作成するだけで問題を回避できました。

class CreditCard < ActiveRecord::Base
  has_one :user, through: :user_profile

  def orders
    user.orders
  end
end

これで問題はほぼ解決しますが、優れた解決策ではありません。

4

0 に答える 0