如何制作周围的红宝石块"conditional"?



我有一个像这样的Ruby块:

<%= a_method("with_argument") do %>
My code...
<% end %>

我想使周围的方法a_method("with_argument")"有条件"Ruby (on Rails)的方式。也就是说,只有当一个条件为真时,a_method("with_argument")才应该是我的内部代码的块。

在这个时候,为了实现这一点,在Ruby on Rails中,我使用这样的代码:

<% my_inner_code = capture do %>
My code...
<% end %>
<% if my_condition %>
<%= a_method("with_argument") do %>
<%= my_inner_code %>
<% end %>
<% else %>
<%= my_inner_code %>
<% end %>

有任何Ruby (on Rails)的方法使周围的块"条件"?

您可以像这样添加一个辅助方法:

def wrap_with_a_method_if(condition, *args, &)
content = capture { yield }
if condition
a_method(*args) { content }
else
content
end
end

并在视图中这样使用:

<%= wrap_with_a_method_if(condition, "with_argument") do %>
My code ...
<% end %>

当包装器不是一个简单的方法调用时:

module ApplicationHelper
class Unwrap
attr_reader :content
def initialize view
@view = view
end
def wrap
@content = @view.capture { yield }
end
end
def wrap condition
unwrap = Unwrap.new self
wrapped = capture do
yield unwrap
end
condition ? wrapped : unwrap.content
end
end
<%= wrap false do |un| %>
<%= tag.div class: "text-blue-500" do %>
<% text = "not wrapped" %>
<%= un.wrap do %>
<%= text %>
<% end %>
<% end %>
<% end %>
#=> not wrapped
<%= wrap true do |un| %>
<%= tag.div class: "text-blue-500" do %>
<% text = "wrapped" %>
<%= un.wrap do %>
<%= text %>
<% end %>
<% end %>
<% end %>
#=> <div class="text-blue-500">wrapped</div>

对于一个通用的方法,把@spickermann的答案再进一步:

def wrap_if(condition, ...)
if condition
send(...)
else
yield
nil # to avoid double concat
end
end
def turbo_frame_tag_if(condition, ...)
wrap_if(condition, :turbo_frame_tag, ...)
end      
<%= turbo_frame_tag_if false, :frame, class: "text-blue-500" do %>
nowrap
<% end %>
#=> nowrap
<%= turbo_frame_tag_if true, :frame, class: "text-blue-500" do %>
wrap
<% end %>
#=> <turbo-frame class="text-blue-500" id="frame">wrap</turbo-frame>

最新更新