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/.