Find coordinates for my database's address column - ruby-on-rails-3

I have my own database that includes: address, lat, long, name.
I have all the addresses that I want without their coordinates. Is there a way to find the coordinates in order to use them as markers on my active map?
In other words I want something to batch?! geocode my addresses that are already in to my database.
Thank you very much
Edited:
def index
if params[:search].present?
#locations = Location.near(params[:search], 20, :order => :distance)
else
#locations = Location.all
#locations.each do |l|
if l.latitude.nil?
new_location = "#{l.address}"
s = Geocoder.search(new_location)
l.latitude = s[0].latitude
l.longitude = s[0].longitude
l.save
end
end
end
This is what I have, but it updates only my first address on the database.

Check out the gmaps4rails gem at https://github.com/apneadiving/Google-Maps-for-Rails
Here's what I use in the model one of my apps:
acts_as_gmappable lat: 'latitude', lng: 'longitude',
process_geocoding: :geocode?,
address: :full_address,
msg: "Sorry, not even Google could figure out where that is"
Oh, and here's my geocode? method:
def geocode?
latitude.blank? || longitude.blank?
end
So when the model's latitude and/or longitude are nil, gmaps4rails automatically does a lookup and fills in the entries.

Related

Accessing geocoder gem scopes

The gem manual indicates Venue.near([40.71, -100.23], 20, :units => :km)
However this application's model objects have two geocoded co-ordinates variables in addition to the individual longitudes and latitudes. In order to test the various search options (postGIS, numerical indexes of lon and lat, or calling geocoder services) is there any way to access a specific model variable in the finding of objects near a given location?
The relevant schema data is:
t.decimal "origin_lon", precision: 15, scale: 10
t.decimal "origin_lat", precision: 15, scale: 10
t.spatial "origin_lonlat", limit: {:srid=>3857, :type=>"point"}
add_index "strappos", ["origin_lat"], :name => "index_strappos_on_origin_lat"
add_index "strappos", ["origin_lon"], :name => "index_strappos_on_origin_lon"
add_index "strappos", ["origin_lonlat"], :name => "index_strappos_on_origin_lonlat", :spatial => true
GeoCoder defaults to using latitude and longitude as their variable names. Since yours are different, you'll need to add an extra option in order to query origin_lon and origin_lat.
In your model, where you initialize geocoder for the model, you have the option of assigning a different name for the lat/lon attribute:
# YourModel.rb
geocoded_by :address,
latitude: :origin_lat,
longitude: :origin_lon
I placed it on multiple lines for clarity. As you can see, I'm telling geocoder that my lat/lon attribute names are different than the defaults.
Now, querying the model using near will look at those new attribute names as opposed to the defaults.

Generate new record from fixture

I have a fixture called "group":
one:
customer: one
name: MyString
In one test I need a couple more so I would like to do something like:
(1..3).each { |t| Group.create!(groups(:one), name: "Group #{t}")}
Is there a way to do something like that with fixtures? (The above of course doesn't work). I know that I could use factories but I want to keep using fixtures.
You can use your fixtures just like active record objects.
# get attr from fixture & delete id
attr_from_fixture = groups(:one).attributes
attr_from_fixture.delete('id')
# create new
(1..3).each do |t|
attr_from_fixture[:name] = "Group #{t}"
Group.create!(attr_from_fixture)
end
UPDATE: even easier
Just remembered the clone method, even easier
(1..3).each do |t|
new_group = groups(:one).clone
new_group.name = "Group #{t}"
new_group.save
end
#dup returns a new object. Clones attrs without id.
(1..3).each do |t|
new_group = groups(:one).dup
new_group.name = "Group #{t}"
new_group.save
end
your second example is a kind of Factory.
if you want to use (yaml) fixtures, you can simply produce them with a script similar to your second example, along the lines of:
y = {"two" => {"customer" => "two", "name" => "londiwe"}}.to_yaml
fi = open("groups.yml", "w")
fi.write(y)
fi.close
edit after comment:
if you just want to take attributes from an existing record and create new records based on that one record, use clone:
1. first find the record you want to clone:
orig = Group.find_by_customer("one")
2. create the clone, change its attributes and save it
(1..3).each do
tmp_clone = orig.clone
tmp_clone.name = "two"
tmp_clone.save
end

Ruby on Rails - search in database based on a query

I have a simple form, where I set up a query that I want to browse, for example panasonic viera.
This is on how I search the term in database:
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
The query looks like %panasonic viera%, but I would need to search the query this way: %panasonic%viera% - I need to find all products, where is in the title the word panasonic or viera... but how to make this query?
One solution would be to break up your query into individual terms and build a set of database queries connected by OR.
terms = params[:q].split
query = terms.map { |term| "name like '%#{term}%'" }.join(" OR ")
Product.where(query).order('price')
If you're using PostgreSQL, you can use pg_search gem. It's support full text search, with option any_word:
Setting this attribute to true will perform a search which will return all models containing any word in the search terms.
Example from pg_search:
class Number < ActiveRecord::Base
include PgSearch
pg_search_scope :search_any_word,
:against => :text,
:using => {
:tsearch => {:any_word => true}
}
pg_search_scope :search_all_words,
:against => :text
end
one = Number.create! :text => 'one'
two = Number.create! :text => 'two'
three = Number.create! :text => 'three'
Number.search_any_word('one two three') # => [one, two, three]
Number.search_all_words('one two three') # => []
How about via ARel
def self.search(query)
words = query.split(/\s+/)
table = self.arel_table
predicates = []
words.each do |word|
predicates << table[:name].matches("%#{word}%")
end
if predicates.size > 1
first = predicates.shift
conditions = Arel::Nodes::Grouping.new(predicates.inject(first) {|memo, expr| Arel::Nodes::Or.new(memo, expr)})
else
conditions = predicates.first
end
where(conditions).to_a
end
This isn't working?
WHERE name LIKE "panasonic" OR name LIKE "viera"

MongoMapper and Gmaps4Rails - Mapping location indexed array field to acts_as_gmappable

I have a model that's backed by Mongodb and I'm trying to get Gmaps4Rails to be able to properly use a location indexed array field that's in my mongo document.
I'm failing to figure out how I should map this given that the latitude and longitude aren't stored as independent values in order to take advantage of the geoindexing on mongo:
class Site
include MongoMapper::Document
include Gmaps4rails::ActsAsGmappable
acts_as_gmappable :lat => ???,
:lon => ???,
:process_geocoding => false
key :name, String
key :location, Array
ensure_index [[:location, '2d']]
end
for now I'm just doing this:
class Site
include MongoMapper::Document
include Gmaps4rails::ActsAsGmappable
acts_as_gmappable :process_geocoding => false
key :name, String
key :location, Array
ensure_index [[:location, '2d']]
def lat
return latitude
end
def lon
return longitude
end
def latitude
return location[1]
end
def longitude
return location[0]
end
end

Using Geocoder, is there a way to save out the street name, city and zip to seperate columns?

I'm in the process of switching my app to use geocoder. In my places table I have columns for address, lat, lng, street_address, city & zip. Using geocoder I'm happily able to fill lat, lng & address columns after validation with with the following in my places model
attr_accessible :address, :lat, :lng
geocoded_by :address, :latitude => :lat, :longitude => :lng
after_validation :geocode, :if => :address_changed?
Is there a way to also have geocoder add the street name, city and zip to three other, separate columns?
I'm still newish to rails so I missed this at first, but hope this helps someone else.
in my model
geocoded_by :address do |obj,results|
if geo = results.first
obj.city = geo.city
obj.lat = geo.latitude
obj.lng = geo.longitude
obj.zip = geo.postal_code
obj.state = geo.state
obj.country = geo.country_code
end
end
and in my view
#tonic.address = params[:address]