Rails:构建关系之间的差异

时间:2013-06-24 06:15:35

标签: ruby-on-rails ruby-on-rails-3 has-many-through

doc有很多articles可以有很多edits

我想为每个edit构建一个article,最多为@doc.articles的总数。此代码适用于第一个版本(即,当尚未存在edits时)。

def editing
  @doc = Doc.find(params[:id])
  unbuilt = @doc.articles - @doc.edits
  unbuilt.reverse.each do |article|
    @doc.edits.build(:body => article.body, :article_id => article.id, :doc_id => @doc.id)
  end
end

但是当edits已经存在时,它会保留那些edits并且仍然为@doc.articles总计构建,最终会导致edits太多,如果只有一个则会有一些重复article已更改。

我想针对:article_idedits中存在的articles提出一些条件(伪代码):

unbuilt = @doc.articles - @doc.edits
unbuilt.where('article_id not in (?)', @doc.edits).reverse.each do |article|
  @doc.edits.build(...)
end

任何帮助都会很棒!非常感谢你。

1 个答案:

答案 0 :(得分:2)

你在做一些奇怪的事情:

unbuilt = @doc.articles - @doc.edits

你可能想要这个

unbuilt = @doc.articles - @doc.edits.map(&:article)

如果@ doc.articles和@ doc.edits是小型集合,则此方法有效,否则首选SQL解决方案。

- 编辑:补充说明 -

这段Ruby

@doc.edits.map(&:article)

相当于

@doc.edits.map do |edit| edit.article end

前一个更紧凑,并利用了ruby 1.9中引入的功能

它基本上采用符号(:article),在其上调用'to_proc'方法(它通过使用'&'字符来实现)。您可以将'to_proc'方法视为与此非常类似的方法:

def to_proc
  proc { |object| object.send(self) }
end

在ruby中,块和触发器通常是等价的(kindof),所以这有效!