0

我有一个与贡献者有 has_many 关系的发布模型。在模型中,我有一个方法可以按行创建 html-ready:

def authors
  authors = []
  Contributor.where(:publication_id => self.id).each do |author|
    authors << "link_to "+author.name+", Contributor.find("+author.id.to_s+")"
  end
  authors.to_sentence
end

在我看来,我有以下几行:

by <%= @publication.authors %>

但它不是渲染链接,而是渲染原始代码,例如:

by link_to B, Contributor.find(1)

我尝试通过将 .html_safe 添加到 @publication.authors 的末尾来修补此问题,但无济于事。有没有更好的方法将这些链接从模型传输到视图?

4

2 回答 2

3

您正在将字符串推入authors数组。它看起来像有效的代码,所以eval在它上面运行应该可以工作。(实际上author.name可能会评估为未定义的符号,所以从头开始。)

更好的方法是在模型上使用has_many :authors, :model => 'Contributor'关系,您可以通过简单地调用Publication来调出对象数组Contributor

@publication.authors

你想在你的视图中迭代这些:

<% @publication.authors.each do |author| %>
  <%= link_to author.name, author %>
<% end %>

另请注意,如果您Publication以这种方式在视图中显示多个对象,则Publication.includes(:authors)在检索它们时需要在控制器中使用它们以避免“N+1”问题。

现在,重复三行代码似乎并不是很昂贵,但是有一些方法可以在不违反 MVC 模式并使模型混乱的情况下干掉它:

  • 将用于打印出版物作者的代码放入部分中,并根据需要调用部分。
  • 将代码放入助手中,包含助手并根据需要调用方法。

这是源代码的一个片段to_sentence(我认为您可以根据需要对其进行调整):

case length
  when 0
    ""
  when 1
    self[0].to_s.dup
  when 2
    "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
  else
    "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
end

完整的源代码可以在这里找到。

于 2012-11-19T18:49:12.873 回答
2

看起来您正在尝试在您的行中使用 haml 语法。也许不是使用link_to,而是使用html超链接标签本身?

话虽这么说,为什么你有一个模型返回 html?

编辑:bdares 已经回答了我想说的话

于 2012-11-19T18:49:26.753 回答