I'm using Rails4, And also using ActsAsParanoid to handle deleted dependencies in my views.
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 %>
...
If i deleted a sauce ActsAsParanoid soft deletes it and save my views from breaking. And the present? method helped me with permanently deleted sauces but As you may see sauces are optional in any ice_cream, So If any ice_cream doesn't have a sauce that will also display deleted value.
So I had to come up with more logic to determine if any ice_cream has no sauce, or had a deleted sauce. So i wrote this helper method.
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
and then used...
app/views/orders/show.html.erb
...
<%= chk(ice_cream, sauce %>
...
But It returnd NoMethodError in Orders#show
undefined method `atr' for #< IceCream:0x007fcae3a6a1c0 >
My questions are...
- What's wrong with my code? and how to fix it?
- Overall, Is my approach considered a good practice to handle such situation?
Sorry I don't yet quite understand the whole situation so there might be a better solution but right now I can't propose it.
What is wrong with your current code I think is how you call
chk. It should beNotice that the second argument is a String instance (or it could a Symbol).
And I think your
chkmethod should be something like thisI just refactored your method so it should be syntactically correct. But I haven't yet checked all those
iflogic.UPDATE
Maybe it would be cleaner this way