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...
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 be
...
<%= chk(ice_cream, 'sauce') %>
...
Notice that the second argument is a String instance (or it could a Symbol).
And I think your chk
method should be something like this
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
I just refactored your method so it should be syntactically correct. But I haven't yet checked all those if
logic.
UPDATE
Maybe it would be cleaner this way
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