2

このリンクに示されている例と同様に、Rails の拡張機能との AR 関連付けがあります: ActiveRecord Association Extensions

has_many :issues, :through => :qbert_issues do
  def tracking
    where("qbert_issues.kind = ?", "tracking")
  end

  def blocking
    where("qbert_issues.kind = ?", "blocking")
  end
end

上記のように、私のものは複数型です...結合テーブルに「種類」列を入力する必要があります。理想的には、これはうまくいくはずです:

q = QBert.find(123)
q.issues.tracking << Issue.find(234)

したがって、記事が示唆しているのは、オーバーロード<<して次のようなことを行うことです。

has_many :issues, ... do
  ...
  def <<(issue)
    issue.kind = "UserAccount"
    proxy_association.owner.issues += [issue]
  end
end

kind が静的であれば、これはいいことです。

これならいけそうだな…

has_many :issues, ... do
  ...
  def <<(*args)
    issue, kind = args.flatten
    issue.kind = kind
    proxy_association.owner.issues += [issue]
  end
end

これにより、少なくともこれを行うことができます:

q = QBert.find(123)
q.issues.tracking << [Issue.find(234), :tracking]

それは私にはあまり乾燥していないようです...もっと良い方法はありますか?kind アクセサーが join table から外れていることを考慮に入れると、ボーナス ポイントが得られますqbert_issuesQBertIssueモデルを介して手動で関連付けを直接追加するだけでよいと思います。

4

1 に答える 1

1

理解した...

def <<(issue)
  kind = where_values.second.scan(/kind = '(.*)'/).flatten.first
  left = proxy_association.reflection.source_reflection
  right = proxy_association.reflection.through_reflection

  left.active_record.create(left.foreign_key.to_sym => issue.id, 
                            right.foreign_key.to_sym => proxy_association.owner.id, 
                            :kind => kind)
end

これにより、次のことができます。

q = QBert.find(123)
q.issues.tracking << Issue.find(234)

where_valuesを解析してパラメーター ハッシュにマージすることで、十分に一般化することができます。

Pry岩、ところで:D

于 2012-11-08T02:37:41.153 に答える