I''m stuck in a catch-22 type problem. I have an insert form for a table that uses the validation in the model. i.e. When you click submit on the form and haven''t filled in the required fields then you get the nice rails error messages saying "field can not be blank". This works fine until I introduce some more logic. What I''m trying to do is to validate the form first and then perform some more validation (using google to verify the address is real) before saving the whole thing. The link if @bstore.valid? just renders the action add but doesn''t show the nice error messages saying the field was blank. Any ideas? Here''s my code so far: def create @bstore = Bookstore.new(params[:bookstore]) if @bstore.valid? addresscheck = params[:bookstore][:address] + " " + params[:bookstore][:city] + ", " + params[:bookstore][:state] + " " + params[:bookstore][:zipcode] address2 = ''q='' + addresscheck url=''http://maps.google.com/maps/geo?'' address = address2 address1 = URI.escape(address) googleoutput = ''&output=xml'' googlekey = ''&key=mykey'' result=URI(url+address1+googleoutput+googlekey ).read doc = Document.new(result.to_s) root = doc.root retstatus = root.elements[''/kml/Response/Status/code''].text if retstatus.to_i == 200 coordinates = root.elements[''/kml/Response/Placemark/Point/coordinates''].text long1, lat1, = coordinates.split('','').map { |v| v.to_f } params[:bookstore][:latitude] = lat1 params[:bookstore][:longitude] = long1 @bookstore = Bookstore.new(params[:bookstore]) if @bookstore.save redirect_to :action => ''add'' flash[:notice] = ''Store was successfully added.'' else render :action => ''add'' end else redirect_to :action => ''add'' flash[:notice] = ''We could not find that address. Please double check the address and try again.'' end else render :action => ''add'' end end -- Posted via http://www.ruby-forum.com/.
On 7/19/06, Chris Williams <chris@designmojo.com> wrote:> > I''m stuck in a catch-22 type problem. I have an insert form for a table > that uses the validation in the model. i.e. When you click submit on the > form and haven''t filled in the required fields then you get the nice > rails error messages saying "field can not be blank". This works fine > until I introduce some more logic. > > What I''m trying to do is to validate the form first and then perform > some more validation (using google to verify the address is real) before > saving the whole thing. > > The link if @bstore.valid? just renders the action add but doesn''t show > the nice error messages saying the field was blank. Any ideas? > > Here''s my code so far: > > def create > @bstore = Bookstore.new(params[:bookstore]) > > if @bstore.valid? > addresscheck = params[:bookstore][:address] + " " + > params[:bookstore][:city] + ", " + params[:bookstore][:state] + " " + > params[:bookstore][:zipcode] > address2 = ''q='' + addresscheck > url=''http://maps.google.com/maps/geo?'' > address = address2 > address1 = URI.escape(address) > googleoutput = ''&output=xml'' > googlekey = ''&key=mykey'' > result=URI(url+address1+googleoutput+googlekey ).read > doc = Document.new(result.to_s) > root = doc.root > retstatus = root.elements > [''/kml/Response/Status/code''].text > > if retstatus.to_i == 200 > coordinates > root.elements[''/kml/Response/Placemark/Point/coordinates''].text > long1, lat1, = coordinates.split('','').map { |v| > v.to_f } > params[:bookstore][:latitude] = lat1 > params[:bookstore][:longitude] = long1 > @bookstore = Bookstore.new(params[:bookstore]) > if @bookstore.save > redirect_to :action => ''add'' > flash[:notice] = ''Store was successfully added.'' > else > render :action => ''add'' > end > > else > redirect_to :action => ''add'' > flash[:notice] = ''We could not find that address. > Please double > check the address and try again.'' > end > else > render :action => ''add'' > end > end > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >It looks like there is a lot of code that could/(should?) go into the model. I think the entire address check should go in there. Since this is effectively a data contrstraint. In your validations you could use the validate method directly and check the address that way. Rails will automagically call this as part of it''s validation check. Couple this with composed of and it should work out pretty neat. Actually I don''t think you even need to use composed_of, but hey. composed_of :store_address, :mapping => [%w( address address), %w(city city), %w(state state), %w(zipcode zipcode)] #(I''m guessing a bit here, ok well a lot) protected def validate tmp = [] # put a can''t be blank on these and collect the values [ :address, :city, :state, :zipcode].each do |method| errors.add( method, "can''t be blank") if !self.store_address.send( method ) tmp << self.store_address.send(method) end return if tmp.include?(nil) # If one was blank, return and don''t bother with the rest since the address won''t be valid # check the google map. I can''t comment on this since I''ve never used it. Just copied what you had. result = URI("http://maps.google.com/maps/geo/?" << URI.escape(tmp.join(" ")) << "&output=xml&key=mykey").read doc = Document.new( result.to_s ) retstatus = doc.root.elements[''/kml/Response/Status/code''].text if retstatus.to_i == 200 self.longitude, self.latitude doc.root.elements[''/kml/Response/Placemark/Point/coordinates''].text.split(",").map { |v| v.to_f } else errors.add( "store_address", "could not be found. Please double check and try again") end end This should add, blank errors, and also errors to say that an address could not be found on google. Then in your controller it becomes very simple def create @bstore = Bookstore.new( params[:bookstore] ) if @bstore.save flash[:notice] = "Store was successfully added" redirect_to :action => "success_action" and return end redirect_to :action => "add" end I hope this works. I haven''t tested it. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060719/91b4e408/attachment-0001.html
Hi Daniel, Thank you very much for the reply. I had a feeling that the google map address search should go into the model but I really didn''t know how to do it. Part of the google call is to get the latitude and longitude of the address in question and insert that along with all the other data. Will this line do it? self.longitude, self.latitude doc.root.elements[''/kml/Response/Placemark/Point/coordinates''].text.split(",").map { |v| v.to_f } Hence the code that I had: coordinates root.elements[''/kml/Response/Placemark/Point/coordinates''].text long1, lat1, = coordinates.split('','').map { |v| v.to_f } params[:bookstore][:latitude] = lat1 params[:bookstore][:longitude] = long1 If your method works then that''ll be awesome!! I''ll try to out and post any questions or problems I run into. Thanks very much. Chris Daniel ----- wrote:> composed_of :store_address, :mapping => [%w( address address), %w(city > city), %w(state state), %w(zipcode zipcode)] > > > #(I''m guessing a bit here, ok well a lot) > protected > def validate > tmp = [] > > # put a can''t be blank on these and collect the values > [ :address, :city, :state, :zipcode].each do |method| > errors.add( method, "can''t be blank") if !self.store_address.send( > method ) > tmp << self.store_address.send(method) > end > return if tmp.include?(nil) # If one was blank, return and don''t > bother > with the rest since the address won''t be valid > > # check the google map. I can''t comment on this since I''ve never used > it. Just copied what you had. > result = URI("http://maps.google.com/maps/geo/?" << > URI.escape(tmp.join(" > ")) << "&output=xml&key=mykey").read > doc = Document.new( result.to_s ) > retstatus = doc.root.elements[''/kml/Response/Status/code''].text > > if retstatus.to_i == 200 > self.longitude, self.latitude > doc.root.elements[''/kml/Response/Placemark/Point/coordinates''].text.split(",").map > { |v| v.to_f } > else > errors.add( "store_address", "could not be found. Please double > check > and try again") > end > end > > This should add, blank errors, and also errors to say that an address > could > not be found on google. > > Then in your controller it becomes very simple > > def create > @bstore = Bookstore.new( params[:bookstore] ) > if @bstore.save > flash[:notice] = "Store was successfully added" > redirect_to :action => "success_action" and return > end > redirect_to :action => "add" > end > > I hope this works. I haven''t tested it.-- Posted via http://www.ruby-forum.com/.
On 7/20/06, Chris Williams <chris@designmojo.com> wrote:> > Hi Daniel, > > Thank you very much for the reply. I had a feeling that the google map > address search should go into the model but I really didn''t know how to > do it. Part of the google call is to get the latitude and longitude of > the address in question and insert that along with all the other data. > > Will this line do it? self.longitude, self.latitude > doc.root.elements > [''/kml/Response/Placemark/Point/coordinates''].text.split(",").map > { |v| v.to_f }I''m not familiar with what doc.root.elements[''/kml/Response/Placemark/Point/coordinates''].text returns but looking at your code I think that line should just do what you had but all in one go. Provided that your model has longitude and latitude attributes of course. I hope it works. As I said, it''s not tested ;) Hence the code that I had:> > coordinates > root.elements[''/kml/Response/Placemark/Point/coordinates''].text > long1, lat1, = coordinates.split('','').map { |v| > v.to_f } > params[:bookstore][:latitude] = lat1 > params[:bookstore][:longitude] = long1 > > If your method works then that''ll be awesome!! > > I''ll try to out and post any questions or problems I run into. Thanks > very much. > > Chris > > > > > Daniel ----- wrote: > > > composed_of :store_address, :mapping => [%w( address address), %w(city > > city), %w(state state), %w(zipcode zipcode)] > > > > > > #(I''m guessing a bit here, ok well a lot) > > protected > > def validate > > tmp = [] > > > > # put a can''t be blank on these and collect the values > > [ :address, :city, :state, :zipcode].each do |method| > > errors.add( method, "can''t be blank") if !self.store_address.send( > > method ) > > tmp << self.store_address.send(method) > > end > > return if tmp.include?(nil) # If one was blank, return and don''t > > bother > > with the rest since the address won''t be valid > > > > # check the google map. I can''t comment on this since I''ve never used > > it. Just copied what you had. > > result = URI("http://maps.google.com/maps/geo/?" << > > URI.escape(tmp.join(" > > ")) << "&output=xml&key=mykey").read > > doc = Document.new( result.to_s ) > > retstatus = doc.root.elements[''/kml/Response/Status/code''].text > > > > if retstatus.to_i == 200 > > self.longitude, self.latitude > > doc.root.elements > [''/kml/Response/Placemark/Point/coordinates''].text.split(",").map > > { |v| v.to_f } > > else > > errors.add( "store_address", "could not be found. Please double > > check > > and try again") > > end > > end > > > > This should add, blank errors, and also errors to say that an address > > could > > not be found on google. > > > > Then in your controller it becomes very simple > > > > def create > > @bstore = Bookstore.new( params[:bookstore] ) > > if @bstore.save > > flash[:notice] = "Store was successfully added" > > redirect_to :action => "success_action" and return > > end > > redirect_to :action => "add" > > end > > > > I hope this works. I haven''t tested it. > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060719/60c07b93/attachment-0001.html
Sorry to bug you again (I''m still learning. :) ) I reverted back to my code so as to understand it a little better but I''m getting an Application error when I try to run this. Any suggestions on what could be causing the problem? Here is the code for my model: class Bookstore < ActiveRecord::Base require ''open-uri'' require "rexml/document" include REXML validates_presence_of :name validates_presence_of :address validates_presence_of :city validates_presence_of :zipcode protected def validate addresscheck = [:address] + " " + [:city] + ", " + [:state] + " " + [:zipcode] address2 = ''q='' + addresscheck url=''http://maps.google.com/maps/geo?'' address = address2 address1 = URI.escape(address) googleoutput = ''&output=xml'' googlekey = ''&key=mykey'' result=URI(url+address1+googleoutput+googlekey ).read doc = Document.new(result.to_s) root = doc.root retstatus= root.elements[''/kml/Response/Status/code''].text if retstatus.to_i == 200 self.longitude, self.latitude = doc.root.elements[''/kml/Response/Placemark/Point/coordinates''].text.split(",").map{ |v| v.to_f } else errors.add( "address", "could not be found. Please double check and try again") end end end -- Posted via http://www.ruby-forum.com/.