我创建了一个代码,该代码允许注册填写“国家/地区”地区和城市字段。我为每个人创建了一个模型。我在表之间建立了关系(请参见下面的代码)。
我创建了另一个模型,因为然后我有了一个搜索表单,该表单由在用户注册时注册的国家,地区,地区和城市的数据库填充。
您认为有一种方法可以更整齐地做到这一点吗?
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%>
答案 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的单元。仅在需要时进行此操作(例如,当您发现编写同一视图组件两次以上时,只是将它们分成多个部分),以避免过度设计。