2

Rails 2.3.x で named_scopes を使用してコードを整理しようとしていますが、 has_many :through 関連付けに苦労しています。スコープを間違った場所に置いているのではないかと思っています...

以下にいくつかの擬似コードを示します。問題は、:accepted という名前のスコープが 2 回複製されることです...もちろん、:accepted を別のものと呼ぶこともできますが、これらはテーブル上のステータスであり、別のものと呼ぶのは間違っているようです。私が次のことを正しく行っているかどうかを誰かが明らかにすることはできますか?

Rails 3 が出ていることは知っていますが、まだベータ版であり、私が行っている大きなプロジェクトであるため、まだ本番環境で使用することはできません。

class Person < ActiveRecord::Base
  has_many :connections
  has_many :contacts, :through => :connections

  named_scope :accepted, :conditions => ["connections.status = ?", Connection::ACCEPTED]
  # the :accepted named_scope is duplicated
  named_scope :accepted, :conditions => ["memberships.status = ?", Membership::ACCEPTED]
end

class Group < ActiveRecord::Base
  has_many :memberships
  has_many :members, :through => :memberships
end

class Connection < ActiveRecord::Base
  belongs_to :person
  belongs_to :contact, :class_name => "Person", :foreign_key => "contact_id"
end

class Membership < ActiveRecord::Base
  belongs_to :person
  belongs_to :group
end

person.contacts.accepted と group.members.accepted のようなものを実行しようとしていますが、これらは 2 つの異なるものです。named_scopes を Membership クラスと Connection クラスに含めるべきではありませんか?

ただし、名前付きスコープをメンバーシップ クラスと接続クラスに配置しようとすると、このエラーが発生します (Person.find(2).contacts は、「受け入れられた」メソッドを持たない人の配列を返すためです。

>> Person.find(2).contacts.accepted
NoMethodError: undefined method `accepted' for #<Class:0x108641f28>

1つの解決策は、Personクラスで2つの異なる名前付きスコープを呼び出すか、別の関連付け(つまり、has_many :accepted_membersとhas_many :accepted_contacts)を作成することですが、それはハックのようで、実際には受け入れただけではありません(つまり. 禁止されたメンバー、無視された接続、保留中、リクエストなど)

4

2 に答える 2

0

personこれは最善の方法ではないと確信しており、groupモデルでこれを行うことができると信じていますが、次の方法もうまくいくと思います。

# models
class Person < ActiveRecord::Base 
  has_many :connections 
  has_many :contacts, :through => :connections

  has_many :memberships
  has_many :groups, :through => :memberships
end 

class Group < ActiveRecord::Base 
  has_many :memberships 
  has_many :members, :through => :memberships
end 

class Connection < ActiveRecord::Base 
  belongs_to :person 
  belongs_to :contact, :class_name => "Person", :foreign_key => "contact_id" 

  named_scope :accepted, :conditions => ["status = ?", Connection::ACCEPTED] 
end 

class Membership < ActiveRecord::Base 
  belongs_to :person 
  belongs_to :group 

  named_scope :accepted, :conditions => ["status = ?", Membership::ACCEPTED] 
end 

# controller
# get person's accepted contacts
@person = Person.first
@person.connections.accepted.map(&:contact)

# get group's accepted members
@group = Group.first
@group.memberships.accepted.map(&:person)
于 2010-06-13T14:47:23.047 に答える
0

あなたはあなた自身の質問に答えました:

named_scopes を Membership クラスと Connection クラスに含めるべきではありませんか?

はい、そうすべきです。これにより、必要に応じてそれらを呼び出すことができます。また、論理的にそれらが属する場所でもあります。

Person で両方をチェックする何かが必要な場合は、次のようにすることができます。

named_scope :accepted, :conditions => ["connections.status = ? OR memberships.status = ?", Connection::ACCEPTED, Membership::ACCEPTED]

たぶん、これをANDにしたいですか?わからない。

于 2010-06-13T02:19:58.210 に答える