当我生成视图

时间:2016-03-22 23:00:43

标签: ruby-on-rails ruby activesupport

我的profile.html.erb在layout.html.erb的上游提供了一个哈希,以包含在元数据中

  <% provide(:twitter, { %>
  <% card: 'summary', %>
  <% site: '@twitter', %>
  <% title: 'Lorem ipsum', %>
  <% description: 'Non sequitar', %>
  <% image: gravatar_for(@user, { size: 150 } )%>
  <% }) %>

layout.html.erb然后应该迭代这个并创建元标记:

  <% yield(:twitter).each do |key, value|%>
  <meta name="twitter:#{key}" content="#{value}" />
  <% end %>

但是,它给了我错误undefined method 'each' for #<ActiveSupport::SafeBuffer:0x007f8d616e5870>,并且在使用yield(:twitter)检查byebug后,我看到我生成ActiveSupport::SafeBuffer的实例:

(byebug) hash = yield(:twitter)
"{:card=&gt;&quot;summary&quot;, :site=&gt;&quot;@twitter&quot;, :title=&gt;&quot;Lorem ipsum&quot;, :description=&gt;&quot;Non sequitar&quot;, :image=&gt;&quot;https://secure.gravatar.com/avatar/a937016807c66d89d0a62d7a1b235533?s=150&quot;}"
(byebug) hash.class
ActiveSupport::SafeBuffer

我可以将字符串评估为哈希值,但ActiveSupport::SafeBuffer将其编码为html safe,并且没有方法可以将原始文件退出。有没有更聪明的方法来做到这一点,或者我是否需要使用帮助器将字符串转换为哈希值,然后eval()将其转换为has?

2 个答案:

答案 0 :(得分:1)

由于provide需要字符串或块,因此最好在帮助器中创建元标记并将其作为字符串参数传递。

SELECT max(l.created) created,
    max(l.id) id,
    l.first_name,
    l.last_name,
    min(ph.number) phone1,
    max(ph.number) phone2,
    e.email email
FROM leads l
    LEFT JOIN lead_phones lp ON lp.lead_id = l.id
    LEFT JOIN phones ph on ph.id = lp.phone_id
    LEFT JOIN lead_emails le ON le.lead_id = l.id
    LEFT JOIN emails e on e.id = le.email_id
GROUP BY l.first_name, l.last_name, e.email

下游视图:

module TwitterHelper
  def twitter_meta_tags(hash)
     hash.each_with_object([]) do |(key, value), array|
        a.push( tag(:meta, { name: "twitter:#{k}", content: v }, false, false ) )
     end.join("\n").html_safe
     # not sure if that last html_safe is really needed.
  end
end

布局:

<%
provide(:twitter, twitter_meta_tags({
  foo: "bar"
}));
%>

使用部分

另一种选择是使用partial并将块而不是字符串传递给<%= yield(:twitter) %>

provide

下游视图:

<% # app/views/twitter/_meta_tags.html.erb %>
<% hash.each do |key, value|%>
  <meta name="twitter:#{key}" content="#{value}" />
<% end %>

布局:

<% provide(:twitter) do %>
  <%= render partial: "twitter/meta_tags", hash: {
    card: 'summary', 
    site: '@twitter',
    title: 'Lorem ipsum',
    description: 'Non sequitar',
    image: gravatar_for(@user, { size: 150 } )
  } %>
<% end %>

答案 1 :(得分:0)

我用以下内容修复了它:

  <% twitter_tags = String.new yield(:twitter)%>
  <% twitter_tags = eval ( CGI.unescapeHTML( twitter_tags ) ) %>

  <% twitter_tags.each do |key, value|%>
    <%= tag(:meta, name: "twitter:#{key}", content: (value) )%>
  <% end %>

恕我直言,这是一个非常丑陋的黑客攻击方式。我会写一个帮手从视图中删除大部分内容,但是,如果你有一个更优雅的解决方案,请分享它,我会接受你的答案,而不是我的。

默认情况下,所有提供的值都是ActiveSupport::SafeBuffer的实例,这会将其转换为字符串,并再次将其计算为哈希值。