Rails帮助使用

时间:2015-02-23 21:24:36

标签: html ruby-on-rails helper

我正在编写一个简单的页面,可以帮助我查看与我的Flickr帐户相比,我的网站自定义库的同步状态。

我有一个简单的循环,它迭代来自Flickr API的响应:

<% for collection in @flickr_hierarchy %>
  <%= traverse_collection(collection, 0) %>
<% end %>

traverse_collection是一个Rails辅助方法,因为:

module GalleryHelper

  def traverse_collection(collection, parent)
    parent = parent == 0 ? 0 : parent["id"]

    content_tag(:tr) do
      content_tag(:td, 'Collection')

      collectionLocal = Collection.where(flickr_id: collection.id).first

      if collectionLocal != nil
        content_tag(:td, 'Yes')
      else
        content_tag(:td, 'No')
      end
      content_tag(:td, '&nbsp;')
      content_tag(:td, '&nbsp;')
      content_tag(:td, collection.title)
      content_tag(:td, collection.id)
      content_tag(:td, parent.to_s)
      content_tag(:td, 'N/A')
      content_tag(:td) do
        if collectionLocal != nil
          button_to('Add all Sets', admin_add_all_sets_for_collection_path(flickr_collection_id: collection.id))
          button_to('Delete Collection', admin_delete_collection_path(flickr_collection_id: collection.id))
        else
          button_to('Add Collection', admin_add_collection_path(flickr_collection_id: collection.id, flickr_parent_collection_id: parent.to_s))
          button_to('Add Collection and Sets', admin_add_all_sets_for_collection_path(flickr_collection_id: collection.id, flickr_parent_collection_id: parent.to_s))
        end
      end
    end
  end

end

不幸的是,我发现没有好的或非杂乱的代码方式来生成在我的页面上输出生成的HTML。

有没有一种好的方法可以做到这一点,或者我应该采取不同的方法。有什么想法吗?

谢谢, 尼尔

3 个答案:

答案 0 :(得分:1)

您可以在辅助方法中使用render

请参阅How to render a view/partial in a helper w/o the layout?

将模板与业务/表示逻辑一起包装在辅助方法中,准备范围并让渲染引擎进行渲染。

这有帮助吗?

<强>更新

你几乎可以调用helper方法中的所有内容,包括render,它将指示Rails引擎将任何视图/部分呈现为请求响应

这是帮助器实现

# app/helpers/application_helper.rb
module ApplicationHelper
  def hello()
    # Prepare your model into locals, which will be passed to your partial
    # template
    render partial: 'shared/hello', locals: {text: 'world'}
  end
end

这是辅助方法

中使用的部分模板
<!-- views/shared/_hello.html.erb -->
<div>hello <%= text %></div>

这是编排请求的主控制器视图

<!-- views/welcome/index.html.erb -->
<h1>Test</h1>
<%= hello %>

答案 1 :(得分:1)

您应该将HTML的程序集从帮助程序移到部分程序中。创建一个文件app/views/gallery/_row.html.erb(您可以随意命名,但确保文件以下划线开头)并将HTML放在那里,如下所示:

<tr>
  <td>Collection</td>
  <td><%= collection_local.present? ? "Yes" : "No" %></td>
  <td>&nbsp;</td>
  <td>&nbsp;</td>
  <td><%= collection.title %></td>
  <td><%= collection.id %></td>
  <td><%= parent %></td>
  <td>N/A</td>
  <td>
    <% if collection_local.present? %>
      <%= button_to(
            "Add all Sets", 
            admin_add_all_sets_for_collection_path(flickr_collection_id: collection.id)
            ) %>
      <%= button_to(
            "Delete Collection",
            admin_delete_collection_path(flickr_collection_id: collection.id)
            ) %>
    <% else %>
      <%= button_to(
            "Add Collection", 
            admin_add_collection_path(
              flickr_collection_id: collection.id, 
              flickr_parent_collection_id: parent.to_s
            )) %>
      <%= button_to(
            "Add Collection and Sets",
            admin_add_all_sets_for_collection_path(
              flickr_collection_id: collection.id, 
              flickr_parent_collection_id: parent.to_s
            )) %>
    <% end %>
  </td>
</tr>

现在你所有的助手都需要调用render,其中包含部分名称和部分需要的“本地人”(变量)。在这种情况下,名称为gallery/row(不带下划线和扩展名的文件名),以及部分需要的变量:collectioncollection_localparent。因此,渲染调用看起来像这样:

module GalleryHelper

  def traverse_collection(collection, parent)
    parent = parent == 0 ? 0 : parent["id"]
    collection_local = Collection.where(flickr_id: collection.id).first

    render(
      partial: "gallery/row",
      locals: {
        collection: collection,
        collection_local: collection_local,
        parent: parent
      })
  end
end

这有帮助吗?

有关如何在官方Ruby on Rails Guides中使用部分内容的更多信息。

答案 2 :(得分:0)

您必须在每个+content_tag的末尾添加一个加号button_to。否则只会创建最后一个content_tag。

module GalleryHelper

  def traverse_collection(collection, parent)
    parent = parent == 0 ? 0 : parent["id"]

    collectionLocal = Collection.where(flickr_id: collection.id).first

    content_tag(:tr) do
      content_tag(:td, 'Collection') +

      content_tag(:td, (collectionLocal != nil) ? 'Yes' : 'No' ) +
      content_tag(:td, '&nbsp;') + 
      content_tag(:td, '&nbsp;') +
      content_tag(:td, collection.title) +
      content_tag(:td, collection.id) +
      content_tag(:td, parent.to_s) +
      content_tag(:td, 'N/A') +
      content_tag(:td) do
        if collectionLocal != nil
          button_to('Add all Sets', admin_add_all_sets_for_collection_path(flickr_collection_id: collection.id)) +
          button_to('Delete Collection', admin_delete_collection_path(flickr_collection_id: collection.id))
        else
          button_to('Add Collection', admin_add_collection_path(flickr_collection_id: collection.id, flickr_parent_collection_id: parent.to_s)) +
          button_to('Add Collection and Sets', admin_add_all_sets_for_collection_path(flickr_collection_id: collection.id, flickr_parent_collection_id: parent.to_s))
        end
      end
    end
  end
end

Rails- nested content_tag