如何制作辅助方法来检查对象的存在状态?
How to make a helper method to check existance status of an object?
我正在使用 Rails4,并且还使用 ActsAsParanoid 来处理我视图中删除的依赖项。
order.rb
class Order < ActiveRecord::Base
...
has_many :ice_creams
accepts_nested_attributes_for :ice_creams
validates :user, :shift, :discount, :total, :total_after_discount, :paid, :remaining, presence: true
...
end
ice_cream.rb
class IceCream < ActiveRecord::Base
...
belongs_to :sauce, with_deleted: true
belongs_to :order
validates :size, :basis, :flavors, :ice_cream_price, :extras_price, :total_price, presence: true
...
end
app/views/orders/show.html.erb
...
<ul>
...
<li>Total:<%= @order.total %><li>
</ul>
<% @order.ice_creams.each do |ice_cream| %>
...
<ul class=leaders>
<li>Ice Craem Id:<%= ice_cream.id %></li>
<li>Sauce:<%= ice_cream.sauce.present? ? ice_cream.sauce.name : "Deleted Value!" %></li>
...
<% end %>
...
如果我删除了一个 sauce
ActsAsParanoid
软删除它并避免我的观点被破坏。 present?
方法帮助我永久删除了 sauces
但正如您所看到的 sauces
在任何 ice_cream
中都是可选的,所以如果任何 ice_cream
没有sauce
也将显示 deleted value
.
所以我不得不想出更多的逻辑来确定是否有 ice_cream 没有酱汁,或者有删除的酱汁。所以我写了这个辅助方法。
application_helper.rb
def chk(obj, atr)
if send("#{obj}.#{atr}_id") && send("#{obj}.#{atr}.present?")
send("#{obj}.#{atr}.name")
elsif send("#{obj}.#{atr}_id.present?") and send("#{obj}.#{atr}.blank?")
"Deleted Value!"
elsif send("#{obj}.#{atr}_id.nil?")
"N/A"
end
end
然后用...
app/views/orders/show.html.erb
...
<%= chk(ice_cream, sauce %>
...
但是它返回了 NoMethodError in Orders#show
undefined method `atr' for #< IceCream:0x007fcae3a6a1c0 >
我的问题是...
- 我的代码有什么问题?以及如何修复它?
- 总的来说,我的方法是否被认为是处理这种情况的良好做法?
抱歉,我还不太了解整个情况,所以可能有更好的解决方案,但现在我不能提出。
我认为您当前的代码有什么问题是您调用 chk
的方式。
应该是
...
<%= chk(ice_cream, 'sauce') %>
...
注意第二个参数是一个 String 实例(或者它可以是一个 Symbol)。
而且我认为你的 chk
方法应该是这样的
def chk(obj, atr)
attribute_id = obj.send("#{atr}_id")
attribute = obj.send(atr)
if attribute_id && attribute.present?
attribute.name
elsif attribute_id.present? and attribute.blank?
"Deleted Value!"
elsif attribute_id.nil?
"N/A"
end
end
我刚刚重构了您的方法,因此它在语法上应该是正确的。但我还没有检查所有这些 if
逻辑。
更新
也许这样会更干净
def chk(obj, attr)
attr_id = obj.send("#{attr}_id")
attr_obj = obj.send(attr)
if attr_id.present?
attr_obj.present? ? attr_obj.name : 'Deleted Value!'
else
'N/A'
end
end
我正在使用 Rails4,并且还使用 ActsAsParanoid 来处理我视图中删除的依赖项。
order.rb
class Order < ActiveRecord::Base
...
has_many :ice_creams
accepts_nested_attributes_for :ice_creams
validates :user, :shift, :discount, :total, :total_after_discount, :paid, :remaining, presence: true
...
end
ice_cream.rb
class IceCream < ActiveRecord::Base
...
belongs_to :sauce, with_deleted: true
belongs_to :order
validates :size, :basis, :flavors, :ice_cream_price, :extras_price, :total_price, presence: true
...
end
app/views/orders/show.html.erb
...
<ul>
...
<li>Total:<%= @order.total %><li>
</ul>
<% @order.ice_creams.each do |ice_cream| %>
...
<ul class=leaders>
<li>Ice Craem Id:<%= ice_cream.id %></li>
<li>Sauce:<%= ice_cream.sauce.present? ? ice_cream.sauce.name : "Deleted Value!" %></li>
...
<% end %>
...
如果我删除了一个 sauce
ActsAsParanoid
软删除它并避免我的观点被破坏。 present?
方法帮助我永久删除了 sauces
但正如您所看到的 sauces
在任何 ice_cream
中都是可选的,所以如果任何 ice_cream
没有sauce
也将显示 deleted value
.
所以我不得不想出更多的逻辑来确定是否有 ice_cream 没有酱汁,或者有删除的酱汁。所以我写了这个辅助方法。
application_helper.rb
def chk(obj, atr)
if send("#{obj}.#{atr}_id") && send("#{obj}.#{atr}.present?")
send("#{obj}.#{atr}.name")
elsif send("#{obj}.#{atr}_id.present?") and send("#{obj}.#{atr}.blank?")
"Deleted Value!"
elsif send("#{obj}.#{atr}_id.nil?")
"N/A"
end
end
然后用...
app/views/orders/show.html.erb
...
<%= chk(ice_cream, sauce %>
...
但是它返回了 NoMethodError in Orders#show
undefined method `atr' for #< IceCream:0x007fcae3a6a1c0 >
我的问题是...
- 我的代码有什么问题?以及如何修复它?
- 总的来说,我的方法是否被认为是处理这种情况的良好做法?
抱歉,我还不太了解整个情况,所以可能有更好的解决方案,但现在我不能提出。
我认为您当前的代码有什么问题是您调用 chk
的方式。
应该是
...
<%= chk(ice_cream, 'sauce') %>
...
注意第二个参数是一个 String 实例(或者它可以是一个 Symbol)。
而且我认为你的 chk
方法应该是这样的
def chk(obj, atr)
attribute_id = obj.send("#{atr}_id")
attribute = obj.send(atr)
if attribute_id && attribute.present?
attribute.name
elsif attribute_id.present? and attribute.blank?
"Deleted Value!"
elsif attribute_id.nil?
"N/A"
end
end
我刚刚重构了您的方法,因此它在语法上应该是正确的。但我还没有检查所有这些 if
逻辑。
更新
也许这样会更干净
def chk(obj, attr)
attr_id = obj.send("#{attr}_id")
attr_obj = obj.send(attr)
if attr_id.present?
attr_obj.present? ? attr_obj.name : 'Deleted Value!'
else
'N/A'
end
end