使用.exists?在 Rails 视图中
Using .exists? in Rails view
我正在开发 Rails 应用程序,该应用程序使用以下方法在特定位置呈现签名:
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
问题是,如果用户没有为模板设置 signature_position
然后尝试打开显示视图,他们将收到 @document.template.signature_position.left
为 nil 的错误。
如果 @document.template.signature_position.left
不存在,则预期的操作是完全忽略签名 div 并呈现页面的其余部分。我尝试按照以下方式使用各种解决方案:
`<%= if document.template.signature_position.left.exists? %>
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
..... extraneous functioning code .....
<% end %>`
但我显然使用了不正确的语法,因为无论我如何更改,我都会遇到各种错误,主要是“期待 keyword_then 或 ';'”或 '\n'"。
Furious Googling 带来了一些有趣的阅读,但到目前为止没有任何用处。有人可以通过建议预期操作的正确语法来提供帮助吗?
你的语法有点不对劲。
<%=
插入表达式的值,但您只想计算条件,所以 <%
就足够了:
<% if document.template.signature_position.left.exists? %>
... code
<% end %>
你的条件语句中也有一个不必要的 ?
(我从上面的例子中删除了)。
我很难想出 "official" ERB 语法的文档,但 Puppet Labs 有一个很好的指南 here。
根据@nick 和@cthulhu 的建议,我想出了一些创建所需功能的解决方法:
<% if @document.template.signature_position.nil? %>
<div></div>
<% else %>
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
.... code ....
<% end %>
几件事:
- ActiveRecord::FinderMethods#exists? 用于检查数据库中的记录,因此这是您将在控制器中而不是在视图中使用的方法。
- 您更有可能希望使用 Object#present?(例如
@document.template.signature_position.left.present?
)在您的视图中有条件地呈现某些代码
- 您正在根据
@document.template.signature_position.left
的结果调用 @document.template.signature_position.top
。您确定不需要先检查这两个值是否都存在吗?
- 您的视图对
@document
对象的深度遍历了解很多,例如它有一个 template
,一个 signature_position
,一个 left
属性。为了与 Law of Demeter 保持一致,这些知识可以从您的视图中清除并进一步推入堆栈。
这是我对第一轮代码重构的看法(做出一些假设):
在您的模型中:
class Document < AR::Base
def left_signature_position
template.signature_position&.left
end
def top_signature_position
template.signature_position&.top
end
def show_signature?
left_signature_position.present? &&
top_signature_position.present?
end
end
那么,在你看来:
<% if @document.show_signature? %>
<div id="signature" style='position: absolute; left: <%= @document.left_signature_position %>px; top: <%= @document.top_signature_position %>px; '>
<% end %>
其他进一步的重构可能包括将生成签名标记的代码放入辅助方法,and/or 为您的 template
添加委托、装饰器 and/or 辅助方法和 signature_position
类 清理模型中现在的 template.signature_position&.top
风格的方法。
我正在开发 Rails 应用程序,该应用程序使用以下方法在特定位置呈现签名:
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
问题是,如果用户没有为模板设置 signature_position
然后尝试打开显示视图,他们将收到 @document.template.signature_position.left
为 nil 的错误。
如果 @document.template.signature_position.left
不存在,则预期的操作是完全忽略签名 div 并呈现页面的其余部分。我尝试按照以下方式使用各种解决方案:
`<%= if document.template.signature_position.left.exists? %>
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
..... extraneous functioning code .....
<% end %>`
但我显然使用了不正确的语法,因为无论我如何更改,我都会遇到各种错误,主要是“期待 keyword_then 或 ';'”或 '\n'"。
Furious Googling 带来了一些有趣的阅读,但到目前为止没有任何用处。有人可以通过建议预期操作的正确语法来提供帮助吗?
你的语法有点不对劲。
<%=
插入表达式的值,但您只想计算条件,所以 <%
就足够了:
<% if document.template.signature_position.left.exists? %>
... code
<% end %>
你的条件语句中也有一个不必要的 ?
(我从上面的例子中删除了)。
我很难想出 "official" ERB 语法的文档,但 Puppet Labs 有一个很好的指南 here。
根据@nick 和@cthulhu 的建议,我想出了一些创建所需功能的解决方法:
<% if @document.template.signature_position.nil? %>
<div></div>
<% else %>
<div id="signature" style='position: absolute; left: <%= @document.template.signature_position.left %>px; top: <%= @document.template.signature_position.top %>px; '>
.... code ....
<% end %>
几件事:
- ActiveRecord::FinderMethods#exists? 用于检查数据库中的记录,因此这是您将在控制器中而不是在视图中使用的方法。
- 您更有可能希望使用 Object#present?(例如
@document.template.signature_position.left.present?
)在您的视图中有条件地呈现某些代码 - 您正在根据
@document.template.signature_position.left
的结果调用@document.template.signature_position.top
。您确定不需要先检查这两个值是否都存在吗? - 您的视图对
@document
对象的深度遍历了解很多,例如它有一个template
,一个signature_position
,一个left
属性。为了与 Law of Demeter 保持一致,这些知识可以从您的视图中清除并进一步推入堆栈。
这是我对第一轮代码重构的看法(做出一些假设):
在您的模型中:
class Document < AR::Base
def left_signature_position
template.signature_position&.left
end
def top_signature_position
template.signature_position&.top
end
def show_signature?
left_signature_position.present? &&
top_signature_position.present?
end
end
那么,在你看来:
<% if @document.show_signature? %>
<div id="signature" style='position: absolute; left: <%= @document.left_signature_position %>px; top: <%= @document.top_signature_position %>px; '>
<% end %>
其他进一步的重构可能包括将生成签名标记的代码放入辅助方法,and/or 为您的 template
添加委托、装饰器 and/or 辅助方法和 signature_position
类 清理模型中现在的 template.signature_position&.top
风格的方法。