想象一下,我有以下代码:
stock = Stock.find_or_initialize_by(ticker: ticker)
if stock.new_record?
stock.assign_attributes(jse_link: link, name: name, price: price)
stock.save!
puts "#{stock.ticker} created successfully with price: #{stock.price}, name: #{stock.name} and can be viewed at #{stock.jse_link}."
elsif stock.jse_link.empty? || stock.name.empty?
stock.update!(jse_link: link, name: name, price: price)
puts "#{stock.ticker} updated successfully with price: #{stock.price}, name: #{stock.name} and can be viewed at #{stock.jse_link}."
elsif !stock.price.eql? price
stock.update!(price: price)
puts "#{stock.ticker} updated successfully with price: #{stock.price}."
end
如何将上述代码重构为DRY&优雅?
答案 0 :(得分:2)
您可能需要考虑Stock
模型中的方法,如下所示:
def patch(price:, new_link:, new_name:)
update(
price: price,
jse_link: (jse_link.presence || new_link),
name: (name.presence || new_name)
)
end
在没有条件的情况下在你的控制器中使用它:
if stock.new_record?
# ...
else
stock.patch(new_link: link, new_name: name, price: price)
end
答案 1 :(得分:0)
您可以使用validations:
class Stock < ActiveRecord::Base
validate :link_and_name, on: :validate_link_and_name
def link_and_name
if jse_link.empty? && name.empty?
errors.add(:link_and_name_empty, 'need to provide link and name')
end
end
end
然后在你的控制器中:
stock.update(price: price)
unless stock.valid?(:validate_link_and_name)
stock.update(jse_link: link, name: name)
end