Rails 助手使用

Rails helper use

我正在编写一个简单的页面,它可以帮助我查看我的网站自定义图库与我的 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 输出到我的页面上。

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

谢谢, 尼尔

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

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

只需将模板与您的 business/presentation 逻辑包装在辅助方法中,准备您的范围并让渲染引擎进行渲染。

有帮助吗?

更新

您几乎可以调用辅助方法中的所有内容,包括 render,这将指示 Rails 引擎将任何 view/partial 呈现为请求响应

这是助手实现

# 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 %>

您必须在每个 content_tagbutton_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

您应该将 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 并使用局部名称和局部所需的 "locals"(变量)。本例中的名称是 gallery/row(不带下划线和扩展名的文件名),partial 需要的变量是: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.

中有更多关于如何使用partials的信息