如何捕获/解决ActiveRecord:保存构建的关联时导致的RecordInvalid异常

chu*_*k w 4 ruby-on-rails associations google-geocoder ruby-on-rails-3

我希望得到一些帮助解决一个问题,我相信你们中的许多人可以在睡梦中避免.

我有两个关系模式.一个包可以有很多位置,一个位置可以有很多包.如果我的位置模型验证失败(例如,由于位置地址为空),我会得到anActiveRecord:RecordInvalid异常.我知道我收到此错误,因为当我调用package.save时,rails会自动调用save!在位置关联.

我不确定如何避免错误或至少挽救错误.你们中的任何人都有关于如何解决问题和Rails最佳实践的任何好建议吗?

这是代码:'

def create
    @package = current_user.package.build(params[:package])
    package_location
    if @package.save
      flash[:success] = "Package created!"
      redirect_to root_path
    else        
      render 'pages/home'
    end
  end

  def package_location
    gps_processing if !session[:gps_aware]
    @package.locations.build(:address => session[:address])
  end

  def gps_processing
    session[:address] = [params[:story][:street_address], params[:story][:city], params[:story][:state], params[:story][:country]].compact.join(', ')
  end

class Package< ActiveRecord::Base

  belongs_to :user
  has_and_belongs_to_many :locations

  validates         :content,   :presence   => true, 
                    :length     => {:maximum => 140}
  validates      :user_id,    :presence => true

  default_scope :order => 'package.created_at DESC'

end

class Location < ActiveRecord::Base

  attr_accessible :lng, :lat, :address

  validates     :lng,       :presence   => true
  validates     :lat,       :presence   => true
  validates     :address,   :presence   => true

  geocoded_by :full_street_address, :latitude => :lat, :longitude => :lng  

  before_validation :geocode

  has_and_belongs_to_many :packages

  def full_street_address
    address
  end
end
Run Code Online (Sandbox Code Playgroud)

"提前感谢您的帮助!

jul*_*lez 15

所选答案不准确.根据这里的文档,有一个简单的方法来捕获救援这个例外:

begin
  complex_operation_that_calls_save!_internally
rescue ActiveRecord::RecordInvalid => invalid
  puts invalid.record.errors
end
Run Code Online (Sandbox Code Playgroud)

您可以访问错误的消息实例变量,并获取关联的字段和错误消息.


chu*_*k w 1

这是我用来解决问题的代码,同时向用户提供关于保存失败原因的良好反馈。请原谅我不优雅的红宝石代码。

仍然存在一个小问题。。。如果包和位置均未通过验证,则重新加载时仅显示位置错误消息。如果用户随后更正了位置错误但未更正包错误,则会向他显示包错误消息。我正在研究如何在第一次重新加载时显示所有错误

  def create
    @package= current_user.package.build(params[:package])
    if package_location && @package.save
        flash[:success] = "Package created!"
        redirect_to root_path
      else
        render 'pages/home'
    end
  end

 def package_location
   gps_processing if !session[:gps_aware]
   location = @package.locations.build(:address => session[:address])
   if !location.valid?
     @package.errors.add(:address, "You have entered an invalid address") 
     return false
   else
      return true
   end
 end

 def gps_processing
   session[:address] = [params[:story][:street_address], params[:story][:city], 
          params[:story][:state], params[:story][:country]].compact.join(', ')
 end
Run Code Online (Sandbox Code Playgroud)