I am hoping to get some help solving a problem that I’m sure many of you could avoid in your sleep.
I have two models in a habtm relationship. A package can have many locations, and a location can have many packages. If my location model fails validation (due to an empty location address, for example), I get anActiveRecord:RecordInvalid exception. I understand that I’m getting this error because when I call package.save, rails automatically calls save! on the location association.
I’m not sure how to avoid the error or at least rescue the error. Do any of you have any good advice, both on how to solve the problem and on Rails best practices?
Here is the code:
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
`
Thanks in advance for your help!
Here’s the code that I used to solve the problem while giving the user good feedback on the why the save failed. Please forgive my inelegant ruby code.
One small problem remains . . . if the package and the location both fail validation, only the location error message is displayed on reload. If the user then corrects the location error but not the package error, he is shown the package error message. I’m working on how to show all of the errors on the first reload