Rails通过has_many:through和association扩展将类型附加到连接表

时间:2012-11-08 01:07:11

标签: ruby ruby-on-rails-3 activerecord associations

我在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

如果善意是静态的,那将是件好事。

看起来我可以这样做......

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]

这对我来说似乎不太干......有更好的方法吗?如果您考虑到类型访问者不在联接表qbert_issues中,则可以获得奖励积分。我猜我只需要直接通过QBertIssue模型手动添加关联。

1 个答案:

答案 0 :(得分: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