如何检查对象上是否存在属性并更新缺失的属性?
How do I check for the existence of attributes on an object and update missing ones?
假设我有以下代码:
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
如何重构上面的代码以使其更加干练和优雅?
您可以使用 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
您可能想在 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
假设我有以下代码:
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
如何重构上面的代码以使其更加干练和优雅?
您可以使用 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
您可能想在 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