latitud actualización de codificación geográfica y la dirección de cada longitud se actualiza

StackOverflow https://stackoverflow.com/questions/4034050

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.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top