Pergunta

I have two models in my Rails app which form a one_to_many relationship. The first model, store, represents a brick and mortar store and has latitude and longitude columns which are being geocoded correctly using the 'geocoder' gem and an address column. The store has_many products. The product has_one store. I would like to return the index of products based on proximity to an address which the user inputs in the search form. Here are the relevant parts of my code as well as my attempt at implementing the search:

in schema.rb:

create_table "products", force: true do |t|
  t.string   "title"
  ...
  t.integer  "store_id"
end

create_table "stores", force: true do |t|
  ...
  t.string   "business_address"
  t.float    "latitude"
  t.float    "longitude"
end

in store.rb

class Store < ActiveRecord::Base
  has_many :products
  geocoded_by :business_address
  after_validation :geocode, :if => :business_address_changed?
end

in product.rb

class Offer < ActiveRecord::Base
  belongs_to :store
end

in views/products/search.html.erb

...
<%= form_tag products_path, :method => 'get' do %>
  <p>
    Find products near<br />
    <%= text_field_tag :custom_address, params[:custom_address] %><br />
  </p>
  <p>
    <%= submit_tag "Search", :name => nil %>
  </p>
<% end %>

in products_controller.rb

def index
  @products = Store.near(params[:custom_address], 100, order: :distance, :select => "products.*")
end

The above index method generates a

ActiveRecord::StatementInvalid in Products#index

error

I am not sure how to continue. Obviously there is a problem with the way I am using the near method and :select but I can't wrap my head around it. How can I return the products sorted by distance?

I am using MySQL as the database adapter; I have heard of issues due to a lack of trig functions with SQLite.

Foi útil?

Solução

I got my code working properly by using the following:

I added an attr_accessor in the Product model:

class Product < ActiveRecord::Base

  belongs_to :store
  attr_accessor :distance_to_user

end

And I changed the index method:

def index
  @products = []
  if params[:custom_address]
    geocoded_stores = (Stores.near(params[:custom_address], 100,))
    geocoded_stores.each do |s|
      s.products.each do |product|
        product.distance_to_user = s.distance
        @products << product
      end
    end
  else
    @products = Product.all
  end
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top