我希望得到一些帮助来解决一个问题,我相信很多人在睡梦中可以避免这些问题。
我有两个关系模式。一个包可以有很多位置,一个位置可以有很多包。如果我的位置模型验证失败(例如,由于位置地址为空),我会得到anActiveRecord:RecordInvalid异常。我知道我收到此错误,因为当我调用package.save时,rails会自动调用save!关于位置关联。
我不确定如何避免错误或至少挽救错误。你们中的任何人都有关于如何解决问题和Rails最佳实践的任何好建议吗?
以下是代码:'
def create
@pacakge = 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
` 在此先感谢您的帮助!
答案 0 :(得分:12)
所选答案不准确。根据文档here,有一个简单的方法来捕获救援这个例外:
begin
complex_operation_that_calls_save!_internally
rescue ActiveRecord::RecordInvalid => invalid
puts invalid.record.errors
end
您可以访问错误的消息实例变量,并获取相关的字段和错误消息。
答案 1 :(得分:2)
我的头脑中有几个想法:
使用@package.save!
和救援区:
def create
@package = current_user.package.build(params[:package])
package_location
@package.save!
flash[:success] = "Package created!"
redirect_to root_path
rescue
render 'pages/home'
end
在您的套餐模型中使用validates_associated,只有在它有效时才会保存:
def create
@package = current_user.package.build(params[:package])
package_location
# You might be able to just use if(@package.save), but I'm not positive.
if(@package.valid?)
@package.save!
flash[:success] = "Package created!"
redirect_to root_path
else
render 'pages/home'
end
end
我确信还有更多方法,因为你在Ruby工作......
希望有所帮助!
答案 2 :(得分:0)
这是我用来解决问题的代码,同时向用户提供有关保存失败原因的良好反馈。请原谅我不雅的红宝石代码。
仍然存在一个小问题。 。 。如果包和位置都验证失败,则重新加载时仅显示位置错误消息。如果用户然后更正位置错误但不纠正包错误,则会显示包错误消息。我正在研究如何在第一次重新加载时显示所有错误
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