latitud actualización de codificación geográfica y la dirección de cada longitud se actualiza
-
26-09-2019 - |
Pregunta
Tengo esto en mi shop.rb
:
def geocode_address
if !address_geo.blank?
geo=Geokit::Geocoders::MultiGeocoder.geocode(address_geo)
errors.add(:address, "Could not Geocode address") if !geo.success
self.lat, self.lng = geo.lat,geo.lng if geo.success
end
end
# Checks whether this object has been geocoded or not. Returns the truth
def geocoded?
lat? && lng?
end
Y en mi shops_controller.rb
:
def update
@shop = Shop.find(params[:id])
if @shop.update_attributes(params[:shop])
flash[:notice] = "Successfully saved."
redirect_to shop_path(@shop, :type => @shop.shop_type)
else
render :action => :edit
end
end
Ahora, cuando el usuario crea en primer lugar la entrada, que se geocodifique la dirección, la latitud y la longitud guardado en la base de datos.
Sin embargo, cuando el usuario actualiza la dirección, la latitud y longitud no será geocodifique más, y por lo tanto sigue utilizando el antiguo latitud y longitud que es el primer salvamento.
¿Cómo escribir a tener cada vez rieles re-codificación geográfica es una entrada actualización?
No puede depender de sólo la dirección porque hay un error en Geokit que cuando trato de mostrar múltiples mapas basados ??en la dirección, sólo la última se muestra.
Estoy usando Geokit, Gmaps, Google Maps ...
Gracias.
Solución
Pongo esto en mi modelo:
before_validation_on_update :geocode_address
Otros consejos
Si el usuario cambia su dirección no puede manejarlo esencialmente la misma forma que una nueva dirección? Es, básicamente, tiene 2 nuevas direcciones sólo tiene que vincular la dirección recién creada con la cuenta del usuario y todo debería funcionar.
La nueva sintaxis para realizar la validación antes de una acción específica es:
before_validation :geocode_address, on: :update
o si tiene más de una acción,
before_validation :geocode_address, on: %i[create update]
Esto asegurará que antes de la validación y guardar en la base de datos está hecho, su método (geocode_address
) se ejecuta en primer lugar.
Es mejor usar Geocoder gema https://github.com/alexreisner/geocoder
En realidad, en su shop.rb modelo que tendrá que añadir lo siguiente para asegurarse de que la longitud y latitud campos se actualizan en la tabla de tienda cada vez que un usuario actualiza la dirección en la vista.
Gemfile
gem 'geocoder', '~> 1.4'
Se debe añadir dos campos a la tabla Shop, longitud y latitud, asegúrese de que son dos flotadores, hacen que la migración si no lo ha hecho ya.
Si se asume que es un campo address
y existe en su mesa tienda, y suponiendo que location.html.erb
es una vista en su tienda y en esa vista que tener algo como esto
<%= f.text_field :address, placeholder: "Your Shop's Address", class: "form-control", required: true, id: "shopaddress" %>
También el supuesto de que, cuando creó su modelo de tienda que ha añadido la propiedad y active:boolean
user:references
saber es una tienda está activo o no, y saber a qué usuario lo hace la tienda pertenecen a. Así que un usuario tiene muchas tiendas.
El shopaddress ID, estoy incluyendo aquí en caso de que desee utilizar joya Geocomplete con Google Maps API con la Biblioteca Lugares. Pero usted no lo necesita allí.
shop.rb
geocoded_by :address
# Will Update if changed
after_validation :geocode, if: :address_changed?
Por supuesto, en su controlador tendrá que asegurarse de que todo el que se actualiza la dirección se autorizó por primera vez y después ejecutar los métodos. Así que en lugar de tener que repetir su auto. Es probable que desee para crear algo como esto en el controlador de tienda.
shops_controller.rb
class ShopsController < ApplicationController
# If your shop owners are creating many shops you will want to add
#your methods here as well with index. Eg. :create, :new
# In case you have a view shop page to show all people
before_action :set_shop, except: [:index]
before_action :authenticate_user!, except: [:show]
# I am assuming that you also want to update other fields in your
#shop and the address isn't the only one.
before_action :is_user_authorised, only: [:name_x, :name_y, :name_z, :location, :update]
def index
@shops = current_user.shops
end
def show
@photos = @shop.photos
@product_reviews = @shop.product_reviews
end
def name_x
end
def name_y
end
def name_z
end
def location
end
def update
new_params = shop_params
# To ensure the shop is actually published
new_params = shop_params.merge(active: true) if is_shop_ready
if @shop.update(new_params)
flash[:notice] = "Saved..."
else
flash[:alert] = "Oh oh hmm! something went wrong..."
end
redirect_back(fallback_location: request.referer)
end
private
def set_shop
@shop = Shop.find(params[:id])
end
def is_user_authorised
redirect_to root_path, alert: "You don't have permission" unless
current_user.id == @shop.user_id
end
# You can play with this here, what defines a ready shop?
def is_shop_ready
!@shop.active && !@shop.name_x.blank? &&
!@shop.name_y.blank? && !@shop.name_z.blank? &&
!@shop.address.blank?
end
# Here you are allowing the authorized user to require her shop and it's properties, so that she can update them with update method above.
# eg_summary, eg_shop_type, eg_shop_name are just additional #example properties that could have been added when you iniitially created your Shop model
def shop_params
params.require(:shop).permit(:address, :active, :eg_shop_name, :eg_shop_summary, :eg_shop_type)
end
end