Как сделать вспомогательный метод для проверки состояния объекта?
Я использую 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
приложение / просмотров / заказы /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
,
Поэтому мне пришлось придумать больше логики, чтобы определить, не было ли у какого-нибудь мороженого соуса или был удален соус. Итак, я написал этот вспомогательный метод.
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
а потом использовал...
приложение / просмотров / заказы /show.html.erb
...
<%= chk(ice_cream, sauce %>
...
Но это возврат NoMethodError in Orders#show
неопределенный метод `atr 'для #
Мои вопросы...
- Что не так с моим кодом? и как это исправить?
- В целом, считается ли мой подход хорошей практикой в такой ситуации?
1 ответ
Извините, я еще не совсем понял всю ситуацию, поэтому может быть лучшее решение, но сейчас я не могу его предложить.
Что не так с вашим текущим кодом, я думаю, как вы называете 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