تحديث خطوط الطول الجيولوجية وخط الطول في كل مرة يتم تحديث عنوانها

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

سؤال

لدي هذا في بلدي 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

وفي بلدي 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

الآن عندما يقوم المستخدم بإنشاء الإدخال لأول مرة ، يتم ترميز العنوان الجغرافي ، مع حفظ خط العرض وخط الطول في قاعدة البيانات.

ولكن عندما يقوم المستخدم بتحديث العنوان ، لن يتم ترميز خطوط الطول والعرض بعد الآن ، وبالتالي لا يزال يستخدم خط العرض والطول القديم الذي يعد أول توفير.

كيف يمكنني الكتابة للحصول على Rails re-geocode في كل مرة يتم فيها تحديث الإدخال؟

لا يمكنني الاعتماد على العنوان فقط لأن هناك خطأ في Geokit أنه عندما أحاول إظهار خرائط متعددة بناءً على العنوان ، يتم عرض آخر مرة فقط.

أنا أستخدم Geokit و Gmaps و Joogle Maps ...

شكرًا.

هل كانت مفيدة؟

المحلول

أضع هذا في نموذجي:

  before_validation_on_update :geocode_address

نصائح أخرى

إذا قام المستخدم بتغيير عنوانه ، فهل يمكنك التعامل معه بشكل أساسي بنفس طريقة عنوان جديد؟ لديك أساسا عنوانان جديدان تحتاج فقط إلى ربط العنوان الذي تم إنشاؤه حديثًا بحساب المستخدم ويجب أن يعمل كل شيء.

بناء الجملة الجديد لإجراء التحقق من الصحة قبل إجراء محدد هو:

     before_validation :geocode_address, on: :update

أو إذا كان لديك أكثر من عمل واحد ،

    before_validation :geocode_address, on: %i[create update]

سيضمن ذلك أنه قبل التحقق من الصحة وحفظه على قاعدة البيانات ، طريقتك (طريقتك (geocode_address) يدير أولا.

من الأفضل استخدام Geocoder Gem https://github.com/alexreisner/geocoder

في الواقع في متجر النماذج الخاص بك. ستحتاج إلى إضافة ما يلي لضمان تحديث حقول الطول وخط الطول في جدول المتجر في كل مرة يقوم المستخدم بتحديث العنوان في عرضك.

Gemfile

gem 'geocoder', '~> 1.4'

يجب عليك إضافة حقلين إلى طاولة المتجر ، وخط الطول وخط العرض ، وتأكد من أنهما عوامان ، وجعل الترحيل إذا لم تكن قد فعلت ذلك بالفعل.

افترض أن address هو حقل وهو موجود في طاولة متجرك ، وافتراض ذلك location.html.erb هو منظر في متجرك وفي هذا الرأي لديك شيء من هذا القبيل

<%= f.text_field :address, placeholder: "Your Shop's Address", class: "form-control", required: true, id: "shopaddress" %>

أفترض أيضًا ذلك ، عندما قمت بإنشاء نموذج متجرك ، أضفت العقار active:boolean و user:references لمعرفة متجر نشط أم لا ، واعرف أي المستخدم الذي ينتمي إليه المتجر. لذلك لدى مستخدم واحد العديد من المتاجر.

The Id Shopaddress ، أنا هنا فقط في حال كنت ترغب في استخدام GEOCOPTE GEM مع Google MAPS API مع مكتبة الأماكن. لكنك لا تحتاجها هناك.

في متجر

geocoded_by :address
# Will Update if changed
after_validation :geocode, if: :address_changed?

بالطبع في وحدة التحكم الخاصة بك ، ستحتاج إلى التأكد من أن كل من يقوم بتحديث العنوان قد أذن أولاً ثم تشغيل الأساليب. لذا بدلاً من الاضطرار إلى تكرار نفسك. ربما ترغب في إنشاء شيء مثل هذا في وحدة تحكم متجرك.

في 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top