有没有一种方法可以分解此搜索代码?

时间:2019-07-11 21:39:59

标签: ruby-on-rails

我创建了一个代码,该代码允许注册填写“国家/地区”地区和城市字段。我为每个人创建了一个模型。我在表之间建立了关系(请参见下面的代码)。

我创建了另一个模型,因为然后我有了一个搜索表单,该表单由在用户注册时注册的国家,地区,地区和城市的数据库填充。

您认为有一种方法可以更整齐地做到这一点吗?

User_model:

belongs_to :country
  belongs_to :region
  belongs_to :district
  belongs_to :city
  # sert à trouver la longitude et la latitude en fonction de l'adresse
  after_validation :geocode
  geocoded_by :full_address
  def full_address
    [self.country.name, self.region.name,self.district.name,self.city.name].compact.join(', ')
  end


  after_initialize do
    self.address ||= Address.new if self.new_record?
  end

# sert à créer les coordonées d'un membre ou d'un partenaire en fonction des champs country_name dans la table Country etc..
  attr_accessor :country_name, :region_name, :district_name, :city_name
  before_validation do
    self.country_id = Country.find_or_create_by(name: self.country_name).id if self.country_name.present?
    self.region_id = Region.find_or_create_by(name:self.region_name,country_id: self.country_id).id if self.region_name.present?
    self.district_id = District.find_or_create_by(name: self.district_name,region_id: self.region_id).id if self.district_name.present?
    self.city_id = City.find_or_create_by(name: self.city_name,district_id: self.district_id).id if self.city_name.present?
  end

Country.rb

class Country < ApplicationRecord
  has_many :users
  has_many :regions
end

Region.rb

class Region < ApplicationRecord
  belongs_to :country
  has_many :districts
  has_many :users
end

District.rb

class District < ApplicationRecord
  belongs_to :region
  has_many :users
  has_many :cities
end

City.rb

class City < ApplicationRecord
  belongs_to :district
  has_many :address
  has_many :users
end

User_controller

def search
    if params[:search].present? || params[:country].present? || params[:city].present? || params[:district].present? || params[:postalCode].present?
      if !params[:region].present?
        @result = Partner.where({country_id:params[:country]})
      elsif !params[:district].present?
        @result = Partner.where({country_id:params[:country],region_id:params[:district]})
      elsif !params[:city].present?
        @result = Partner.where({country_id:params[:country],region_id:params[:district],district_id:params[:district]})
      elsif !params[:postalCode].present?
        @result = Partner.where({country_id:params[:country],region_id:params[:region],district_id:params[:district],city_id:params[:city]})
      else
        @result = @partner_with_address.where(addresses:{city:params[:city],district:params[:district],country:params[:country],postal_code:params[:postalCode]})
      end
    else
      @result = Partner.all
    end
    respond_to do |format|
      format.js
    end
  end

search_form:

<%= form_tag(search_url, method: :get, :remote => true) do %>
    <div class="inner-form">
      <div class="basic-search">
        <div class="input-field">
          <%= text_field_tag :search,nil,placeholder:t('search_form.type_your_keywords'), id:"search", type:"text" %>
          <div class="icon-wrap">
            <svg class="svg-inline--fa fa-search fa-w-16" fill="#ccc" aria-hidden="true" data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
              <path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path>
            </svg>
          </div>
        </div>
      </div>
      <div class="advance-search">
        <span class="desc"><%= t('search_form.advanced_search').upcase%></span>
        <div class="row">
          <div class="input-field">
            <div class="input-select">

              <%=select_tag :country, options_for_select(Country.all.collect{|p| [p.name, p.id]}, selected: params[:country]), prompt:t('search_form.country'), id:"country",class:"countries order-alpha",style:"height:50px" %>
            </div>
          </div>
          <div class="input-field">
            <div class="input-select">
              <%=select_tag :region,options_from_collection_for_select(Region.order(:name),:id,:name, params[:region]), prompt:t('search_form.district'),id:"region",class:"states order-alpha", style:"height:50px" %>
            </div>
          </div>
          <div class="input-field">
            <div class="input-select">
              <%=select_tag :district,options_from_collection_for_select(District.order(:name),:id,:name,params[:district]),  prompt:t('search_form.district'),id:"district",class:"states order-alpha", style:"height:50px" %>
            </div>
          </div>
          <div class="input-field">
            <div class="input-select">
              <%=select_tag :city,options_from_collection_for_select(City.order(:name),:id,:name,params[:city]), prompt:t('search_form.city'), id:"city",class:"cities order-alpha",style:"height:50px" %>
            </div>
          </div>
          <div class="input-field">
            <div class="input-select">
              <%= text_field_tag :postal_code,params[:postal_code], placeholder:t('search_form.postalCode'), id:"search", type:"text",style:"height:50px" %>
            </div>
          </div>
        </div>
        <div class="row third">
          <div class="input-field">
            <div class="group-btn">

              <button class="button ripple-effect"><%= t('search_form.search').upcase%></button>
            </div>
          </div>
        </div>
      </div>
    </div>
  <%end%>

1 个答案:

答案 0 :(得分:0)

您可以将模型中的逻辑分为关注点,并在需要时包括它们。

https://www.sitepoint.com/dry-off-your-rails-code-with-activesupportconcerns/

更重要的是,您可以为搜索创建一些查询对象,例如可以将params [:search]逻辑重构为使用PartnerQuery,然后在控制器中执行@result = PartnerQuery.new(.。 。)。call(params)。

https://mkdev.me/en/posts/how-to-use-query-objects-to-refactor-rails-sql-queries-这里有一些很好的例子

根据组件的重用方式/形式,表单可以分为部分或部分。如果您想更多地参与进来,请考虑进入Thoughtbot的单元。仅在需要时进行此操作(例如,当您发现编写同一视图组件两次以上时,只是将它们分成多个部分),以避免过度设计。