我正在创建一个搜索标签,用户可以在其中搜索具有特定类型的餐馆。我有3种型号:餐厅,类型和餐厅类型。由于一家餐馆可以有多种类型,我创建了一个RestaurantType关系表。
如何创建此类搜索标签?
我发现最接近这个问题的StackOverflow问题如下:novelty detection,但它并未涵盖我所需要的全部内容。也就是说,我对Rails还是一个新手,也许只需要一个更有指导性的答案。
restaurant.rb
has_many :types, :through => :restaurant_types
type.rb
has_many :restaurants, :through => :restaurant_types
restaurant_type.rb
belongs_to :restaurant
belongs_to :type
restaurants_controller.rb(索引操作)(我还按名称实施搜索,这是餐厅的属性)
@restaurants = Restaurant.joins(restaurant_type: :type).where
("cast(type_id as text) LIKE ?", "%#{params[:type]}%")
@restaurants = @restaurants.where("restaurant_name LIKE ?",
"%#{params[:restaurant_name]}%").paginate(:page => params[:page],
:per_page => 8)
restaurants / index.html.erb (仅限搜索部分)
<%= form_tag(restaurants_path, :method => 'get') do %>
<%= text_field_tag :restaurants_name, params[:restaurants_name], :placeholder => "Name" %>
<%= select_tag :restaurant_type_id, options_for_select(Type.all.map{ |t| [t.type_name, t.id] }) %>
<%= submit_tag "Search" %>
<% end %>
备注:
-
restaurants_controller.rb
def index
@types = RestaurantType.where("type_id LIKE ?", "%#{params[:type_id]}%")
array = []
@types.each do |t|
@restaurant = Restaurant.find(t.restaurant_id)
array.push(@restaurant)
end
@restaurant = WillPaginate::Collection.create(1, 6, array.length) do |pager|
pager.replace array
end
end
restaurants / index.html.erb(form_tag的一部分)
<%= select_tag :type_id, options_for_select(Type.all.map{ |t| [t.type_name, t.id] }) %>
-
if (params[:type_id].to_f > 0)
array = []
RestaurantType.where("type_id = #{ params[:type_id] } ").each do |t|
array.push(t.school_id)
end
@restaurants = Restaurant.where("restaurant_name LIKE ? AND cast(city_id as text) LIKE ? AND id in (?)", "%#{ params[:restaurant_name] }%",
"%#{params[:city_id]}%", array).paginate(:page => params[:page], :per_page => 6)
else
@restaurants = Restaurant.where("restaurant_name LIKE ? AND cast(city_id as text) LIKE ?", "%#{params[:restaurant_name]}%",
"%#{params[:city_id]}%").paginate(:page => params[:page], :per_page => 6)
end
答案 0 :(得分:0)
我认为错误来自于restaurants_controller的加入:
@restaurants = Restaurant.joins(restaurant_type: :type).where("cast(type_id as text) LIKE ?", "%#{params[:type]}%")
您必须使用与模型中指定的完全相同的名称...在这种情况下,'restaurant_types'而不是'restaurant_type'。
但是,您已经在模型文件中创建了模型之间的关联,因此您不需要使用连接。你可以这样搜索:
@restaurants = Type.find(params[:restaurant_type_id]).restaurant.where('restaurant_name like ?', "%#{params[:restaurant_name]}%")
我会将type.rb中的关联更改为:
has_many :restaurants, :through => :restaurant_types
然后,从类型中查找餐馆的方法将是复数,更直观。
答案 1 :(得分:0)
我决定创建一个包含所选类型的所有餐厅的数组。该算法使用所选类型遍历每个对象(restaurant_type),将其推送到数组中,并在索引上对数组进行分页。
可能需要更长时间,但渐近分析表明T(n)乘以常数,这不是什么大不了的事。
感谢那位在这里回答分页数组的家伙:Paginating an Array in Ruby with Will_Paginate
<强> restaurants_controller.rb 强>
def index
@types = RestaurantType.where("type_id LIKE ?", "%#{params[:type_id]}%")
array = []
@types.each do |t|
@restaurant = Restaurant.find(t.restaurant_id)
array.push(@restaurant)
end
@restaurant = WillPaginate::Collection.create(1, 6, array.length) do |pager|
pager.replace array
end
end
restaurants / index.html.erb(form_tag的一部分)
<%= select_tag :type_id, options_for_select(Type.all.map{ |t| [t.type_name, t.id] }) %>
-
if (params[:type_id].to_f > 0)
array = []
RestaurantType.where("type_id = #{ params[:type_id] } ").each do |t|
array.push(t.school_id)
end
@restaurants = Restaurant.where("restaurant_name LIKE ? AND cast(city_id as text) LIKE ? AND id in (?)", "%#{ params[:restaurant_name] }%",
"%#{params[:city_id]}%", array).paginate(:page => params[:page], :per_page => 6)
else
@restaurants = Restaurant.where("restaurant_name LIKE ? AND cast(city_id as text) LIKE ?", "%#{params[:restaurant_name]}%",
"%#{params[:city_id]}%").paginate(:page => params[:page], :per_page => 6)
end