2

Adoc有很多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,最终会出现太多和一些重复。editsarticle

我想提出一些:article_id在两者中都存在的edits条件articles(在伪代码中):

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

任何帮助都会很棒!太感谢了。

4

1 回答 1

2

你在这里做了一些奇怪的事情:

unbuilt = @doc.articles - @doc.edits

你可能想要这个

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

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

-- 编辑:添加解释 --

这块红宝石

@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​​ 中,blocks 和 procs 通常是等价的(kindof),所以这行得通!

于 2013-06-24T07:02:37.647 回答