Фильтр с несколькими тегами select_tags не отправляет запрос - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть фильтр, где вы можете фильтровать рестораны по стилю питания, цене и площади.Пользователь может выбрать стиль, цену и площадь из выпадающего меню, а затем нажать кнопку фильтра.Тем не менее, это, кажется, ничего не фильтрует.Например, выбрав «Итальянский» в качестве стиля, «€елье» в качестве цены и «Ибица» в качестве области, я получаю следующие параметры: http://localhost:3000/restaurants?utf8=%E2%9C%93&tags=italian&price=%E2%82%AC%E2%82%AC&municipal=Ibiza&commit=Filter

Моя форма:

<%= form_tag index_ibiza_path, method: :get do %>
  <%= select_tag "tags", options_for_select([ "steakhouse", "mexican", "italian", "indian", "chinese", "thai", "french", "seafood" ]), include_blank: true %>
  <%= select_tag "price", options_for_select([ "€", "€€", "€€€"]), include_blank: true %>
  <%= select_tag "municipal", options_for_select([ "Ibiza", "Santa Eulalia del Río", "San José", "San Antonio Abad", "San Juan Bautista", "Es Caló de Sant Agustí", "San Francisco Javier", "La Savina", "Es Pujols / Sant Ferran de Ses Roques", "El Pilar de La Mola"]), include_blank: true %>
  <%= submit_tag "Filter" %>
<% end %>

Мой контроллер:

class RestaurantsController < ApplicationController
  skip_before_action :authenticate_user!, only: [
    :index,
    :show,
    :featured,
    :ibiza,
    :formentera,
    :restaurant_ibiza,
    :beach_restaurant_ibiza,
    :cafe_ibiza,
    :restaurant_formentera,
    :beach_restaurant_formentera,
    :cafe_formentera,
    :tagged,
    :index_ibiza,
    :index_formentera
  ]
  before_action :set_restaurant, only: [ :show, :edit, :update, :destroy ]

  def index
    if params[:query].present?
      if @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).search_by_name_city_or_island(params[:query]).present?
        @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).search_by_name_city_or_island(params[:query])
        markers(@restaurants)
      else
        render :no_results_search
      end
    else
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).all.order(:name)
      markers(@restaurants)
    end
  end

  def index_ibiza
    @restaurants_ibiza = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:query])
    if @restaurants_ibiza
      markers(@restaurants)
    else
      render :no_results
    end
  end

  def index_formentera
    @restaurants_formentera = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Formentera').search_by_name_city_or_island(params[:query])
    if @restaurants_formentera.present?
      @restaurants_formentera
      markers(@restaurants)
    else
      render :no_results
    end
  end

  def ibiza
    @restaurants = Restaurant.where(featured: true)
    @ibiza_town = Restaurant.where(zipcode: "07800") || Restaurant.where(geo_city: 'Ibiza Town')
    @santa_eulalia = Restaurant.where(zipcode: ["07840", "07849"])
    @san_jose = Restaurant.where(zipcode: ["07817", "07818", "07829", "07830", "E-07830", "07839"])
    @san_antonio = Restaurant.where(zipcode: ["07820", "07816"])
    @san_juan = Restaurant.where(zipcode: ["07240", "07810", "07815"])
  end

  def restaurant_ibiza
    results_ibiza(@restaurants)
  end

  def beach_restaurant_ibiza
    results_ibiza(@restaurants)
  end

  def cafe_ibiza
    results_ibiza(@restaurants)
  end

  def formentera
    @restaurants = Restaurant.where(featured: true)
    @es_calo = Restaurant.where(zipcode: ["07872"])
    @san_francisco = Restaurant.where(zipcode: ["07860"])
    @la_savina = Restaurant.where(zipcode: ["07870"])
    @es_pujols_sant_ferran = Restaurant.where(zipcode: ["07871"])
    @el_pilar = Restaurant.where(zipcode: ["07872"])
  end

  def restaurant_formentera
    results_formentera(@restaurants)
  end

  def beach_restaurant_formentera
    results_formentera(@restaurants)
  end

  def cafe_formentera
    results_formentera(@restaurants)
  end

  def featured
    @restaurants = Restaurant.where(featured: true)
  end

  def tagged
    if params[:tag].present?
      @restaurants = Restaurant.tagged_with(params[:tag])
      markers(@restaurants)
    else
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).all.order(:name)
      markers(@restaurants)
    end
  end

  def show
    @related_restaurants = @restaurant.find_related_tags
    @markers = [{
      lng: @restaurant.longitude,
      lat: @restaurant.latitude,
      infoWindow: { content: render_to_string(partial: "/restaurants/map_window", locals: { restaurant: @restaurant }) }
    }]
  end

  def new
    @restaurant = Restaurant.new
  end

  def create
    @restaurant = Restaurant.new(restaurant_params)
    @restaurant.user = current_user
    if @restaurant.save
      redirect_to restaurant_path(@restaurant)
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @restaurant.update(restaurant_params)
      redirect_to restaurant_path(@restaurant)
    else
      render :edit
    end
  end

  def destroy
    @restaurant.destroy
    redirect_to restaurants_path
  end

  private

  def set_restaurant
    @restaurant = Restaurant.find(params[:id])
  end

  def results_ibiza(restaurants)
    if @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').where(category: params[:query]).present?
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').where(category: params[:query])
      markers(@restaurants)
    else
      render :no_results
    end
  end

  def results_formentera(restaurants)
    if @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Formentera').where(category: params[:query]).present?
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Formentera').where(category: params[:query])
      markers(@restaurants)
    else
      render :no_results
    end
  end

  def markers(restaurants)
    if @restaurants
      @markers = @restaurants.map do |restaurant|
        {
         lng: restaurant.longitude,
         lat: restaurant.latitude,
         infoWindow: { content: render_to_string(partial: "/restaurants/map_window", locals: { restaurant: restaurant }) }
        }
      end
    elsif @restaurants_ibiza
      @markers = @restaurants_ibiza.map do |restaurant|
        {
         lng: restaurant.longitude,
         lat: restaurant.latitude,
         infoWindow: { content: render_to_string(partial: "/restaurants/map_window", locals: { restaurant: restaurant }) }
        }
      end
    else
       @markers = @restaurants_formentera.map do |restaurant|
        {
         lng: restaurant.longitude,
         lat: restaurant.latitude,
         infoWindow: { content: render_to_string(partial: "/restaurants/map_window", locals: { restaurant: restaurant }) }
        }
      end
    end
  end

  def restaurant_params
    params.require(:restaurant).permit(
      :name,
      :address,
      :full_address,
      :zipcode,
      :phone,
      :email,
      :facebook,
      :instagram,
      :twitter,
      :website,
      :city,
      :island,
      :featured,
      :active,
      :style,
      :price,
      :rating,
      :longitude,
      :latitude,
      :description,
      :opening_hours_morning,
      :closing_hours_morning,
      :opening_hours_afternoon,
      :closing_hours_afternoon,
      tag_list: [],
      images: []
      )
  end
end

Это маршруты:

    Rails.application.routes.draw do
  root to: 'restaurants#featured'
  get '/tagged', to: "restaurants#tagged", as: :tagged
  get 'index_ibiza', to: "restaurants#index_ibiza", as: :index_ibiza
  get 'index_formentera', to: "restaurants#index_formentera", as: :index_formentera
  devise_for :users

  require "sidekiq/web"
  authenticate :user, lambda { |u| u.admin } do
    mount Sidekiq::Web => '/sidekiq'
  end

  resources :restaurants do
    collection do
      get 'featured', to: 'restaurants#featured'
      get 'ibiza', to: 'restaurants#ibiza'
      get 'formentera', to: 'restaurants#formentera'
      get 'restaurant_ibiza', to: 'restaurants#restaurant_ibiza'
      get 'beach_restaurant_ibiza', to: 'restaurants#beach_restaurant_ibiza'
      get 'cafe_ibiza', to: 'restaurants#cafe_ibiza'
      get 'restaurant_formentera', to: 'restaurants#restaurant_formentera'
      get 'beach_restaurant_formentera', to: 'restaurants#beach_restaurant_formentera'
      get 'cafe_formentera', to: 'restaurants#cafe_formentera'
    end
  end
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

Если кто-нибудь может мне помочь.Я понятия не имею, что мне нужно сделать, чтобы это исправить.

Это модель:

class Restaurant < ApplicationRecord
  belongs_to :user
  has_many_attached :images
  acts_as_taggable_on :tags
  geocoded_by :address
  after_validation :geocode, if: :will_save_change_to_address?
  reverse_geocoded_by :latitude, :longitude, address: :full_address
  after_validation :reverse_geocode
  after_validation :save_city_zipcode, :assign_zipcode_to_municipal

  def save_city_zipcode
    self.zipcode = Geocoder.search([self.latitude, self.longitude]).first.data["address"]["postcode"]
  end

  def assign_zipcode_to_municipal
    case self.zipcode
    when "07800"
      return self.municipal = "Ibiza"
    when "07840", "07849"
      return self.municipal = "Santa Eulalia del Río"
    when "07817", "07818", "07829", "07830", "E-07830", "07839"
      return self.municipal = "San José"
    when "07820", "07816"
      return self.municipal = "San Antonio Abad"
    when "07240", "07810", "07815"
      return self.municipal = "San Juan Bautista"
    when "07872"
      return self.municipal = "Es Caló de Sant Agustí"
    when "07860"
      return self.municipal = "San Francisco Javier"
    when "07870"
      return self.municipal = "La Savina"
    when "07871"
      return self.municipal = "Es Pujols / Sant Ferran de Ses Roques"
    when "07872"
      return self.municipal = "El Pilar de La Mola"
    else
      return self.municipal = ""
    end
  end

  # Validations
  validates :name, presence: true, length: { minimum: 2 }
  validates :island, inclusion: { in: ["Ibiza", "Formentera"] }
  validates :price, inclusion: { in: ["€", "€€", "€€€"] }
  validates :website, format: { with: /\A(http|ftp|https)?(\:\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^!=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])+$\z/,
    message: "only allows url links" } , allow_blank: true, presence: false
  validates :rating, inclusion: { in: [1, 2, 3, 4, 5] }
  validates :description, presence: true, allow_blank: false
  validates :images, attached: true, content_type: ['image/png', 'image/jpg', 'image/jpeg'], allow_blank: true, presence: false

  include PgSearch
  pg_search_scope :search_by_name_city_or_island,
      :against => [ :name, :municipal, :city, :island, :price],
      :associated_against => {
         :tags => [:name]
        },
      :using => {
        :tsearch => { :prefix => true },
        :trigram => {
          :threshold => 0.1,
          :only => [ :name, :city, :island, :municipal, :price ]
        }
      },
      :ignoring => :accents,
      :ranked_by => ":trigram"

end

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Итак, с некоторой помощью я обнаружил, что проблема в том, что я забыл изменить метод в форме на метод post.С методом get контроллер не получает его иначе.Я также заставил контроллер принимать каждый параметр на основе его имени в форме.Итак, чтобы показать вам, что я сделал, вот как у меня теперь есть контроллер:

def index_ibiza
    if params[:tags].present?
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:tags])
      markers(@restaurants)
    elsif params[:price].present?
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:price])
      markers(@restaurants)
    elsif params[:municipal].present?
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:municipal])
      markers(@restaurants)
    else
      @restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').order(:name)
      markers(@restaurants)
    end
  end

Вы видите, что я назвал каждый параметр по имени в форме.Вот как выглядит форма:

<div class="container index-container content" style="margin-bottom: 0px;">
  <div class="row">
    <div class="col-sm-12">
      <form action="" class="form-inline">
        <div class="form-group">
          <%= form_tag index_ibiza_path, method: :post do %>
            <%= select_tag :tags, options_for_select([ "steakhouse", "mexican", "italian", "indian", "chinese", "thai", "french", "seafood" ]), include_blank: true %>
            <%= select_tag :price, options_for_select([ "€", "€€", "€€€"]), include_blank: true %>
            <%= select_tag :municipal, options_for_select([ "Ibiza", "Santa Eulalia del Río", "San José", "San Antonio Abad", "San Juan Bautista", "Es Caló de Sant Agustí", "San Francisco Javier", "La Savina", "Es Pujols / Sant Ferran de Ses Roques", "El Pilar de La Mola"]), include_blank: true %>
            <%= submit_tag "Filter" %>
          <% end %>
        </div>
      </form>
    </div>
  </div>
</div>

Итак, я проделал то же самое с другими имеющимися у меня индексами:

  • ibiza_index: куда приходят пользователи, когда нажимают остров => ibiza, foodstyle => китайский (результаты отфильтрованы на ибице + китайский)
  • ibiza_restaurant / _beach_restaurant / _cafe: куда пользователи приходят, когда нажимают остров => ibiza, тип ресторана => ресторан или пляжный ресторан или кафе (результаты отфильтрованы на ibiza + restaurant или _beach_restaurant или _cafe)
  • formentera_index: см. ibiza_index, но затем island => formentera
  • formentera_restaurant: см. ibiza_restaurant, но затем island => formentera

Отдельное спасибо @Dimitrius Lachi и @Chiel Hackman (из Rubyна Rails Developer fb group) за помощь.

0 голосов
/ 18 декабря 2018

В вашей форме вы никогда не предоставляете для контроллера параметр query, и у вас есть условное if params[:query].present?.Ваш контроллер когда-либо вернет:

@restaurants_ibiza = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza')
 markers(@restaurants)

Кроме того, я настоятельно рекомендую вам не дублировать ваш запрос для if конфинативного внутри вашего контроллера:

if @restaurants_ibiza = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:query]).present?
    @restaurants_ibiza = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:query])

Вы можете сделатьследующее:

@restaurants = Restaurant.where.not(latitude: nil, longitude: nil).where(island: 'Ibiza').search_by_name_city_or_island(params[:query])
if @restaurants
  markers(@restaurants)
else
  render :no_result
end

И, для вашего html, вы должны использовать options_for_collect, см .: https://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag

...