rails中的before_save回调顺序

时间:2015-04-23 21:34:49

标签: activerecord

我正在尝试对地址进行地理编码,我正在尝试对名为full_address的非持久属性进行地理编码。这是我的代码:

class Company < ActiveRecord::Base
  include ActiveModel::Dirty

  validates :name, :organization, :title, :state, :city, presence: true
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, }

  before_save :full_address
  geocoded_by :full_address

  before_save :geocode, if: ->(obj){obj.full_address.present? && (obj.city_changed? || obj.state_changed?)}

  def full_address
    "#{city}, #{state}"
  end
end

 我不确定我的before_save回调是否以正确的顺序触发。基本上,我如何确保

before_save :full_address

在另一个之前开火?

我查看了around_save文档,但我仍然不确定它在做什么。

1 个答案:

答案 0 :(得分:1)

Jwan -

AR回调的使用有很多原因,它们对于处理数据库中的记录特别有帮助,但是你不需要在这里为'full_address&#39;提供回复。为什么呢?

因为它所做的就是返回一个字符串,不对数据库执行操作或以任何方式更改数据。

自从我使用geocoder gem之后已经有一段时间了,但是在你的其他before_save回调中,你正在传递lambdha进行条件操作。

夫妻俩:

1。)您正在检查是否存在插值字符串,但验证了在回调之前触发的两个插值属性的存在,因此obj.full_address.present?应始终返回true,因为它如果不存在这些属性中的一个或甚至其中一个属性,那么将会破坏验证。尝试

before_save :geocode, if: ->(obj){ obj.city_changed? || obj.state_changed? }

+1虽然在ActiveModel :: Dirty实现!

2.。)除非您使用的是旧版本的Rails或明确配置它,否则ActiveModel::Dirty会自动加载;不需要line 2

3.)我也会尝试使用after_validation回调而不是before_save。无法保证能够解决问题,但它在回调堆栈中更早。请参阅http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html