Heyo。一直试图解决这个问题,但我已经被困了太长时间而且只是变得痛苦!
我正在尝试使用“高级搜索”表单,允许您根据其他模型中的设置搜索“用户”。例如搜索名为Jim的用户,他做跑步,减肥作为他的目标。
我有三种模式:
到目前为止,我已设法使其工作,因此我可以通过选择框搜索用户模型中的内容(例如名称)以及用户体育。我无法工作的是搜索用户目标,我不明白为什么。
我只能搜索目标而没有其他字段时,“没有人似乎有这些偏好”。
我尝试使用与我的体育相同的代码,但这不起作用(猜测因为不同的关系?)
# searches/show.html.erb
<% if @search.search_users.empty? %>
<p>Nobody seems to have these preferences</p>
<% else %>
<% @search.search_users.each do |u| %>
<tr>
<td><%= u.name %></td>
<% u.sports.each do |s| %>
<td><%= s.name %></td>
<% end %>
<% u.goals.each do |g| %>
<td><%= g.name %></td>
<% end %>
</tr>
<% end %>
我在控制台中完成了关联,当我输入例如u.goals时,我得到了这个(当我查询用户与目标相关联时,反之亦然):
irb(main):015:0> u.goals
=> #<ActiveRecord::Associations::CollectionProxy [#<Goal id: 1, name: "Weight Loss", user_id: 1>, #<Goal id: 3, name: "Strength", user_id: 1>]>
这是我目前的代码:
# user.rb
class User < ApplicationRecord
has_and_belongs_to_many :sports
has_many :goals, :foreign_key => :goal_id
end
# sport.rb
class Sport < ApplicationRecord
has_and_belongs_to_many :users
end
# goal.rb
class Goal < ApplicationRecord
belongs_to :user, :foreign_key => :goal_id
end
我的搜索内容:
# search.rb
def search_users
users = User.all
users = users.where("users.name ILIKE ?", "%#{keywords}%") if keywords.present?
users = users.joins(:sports).where("sports.name ILIKE ?", "%#{name}%") if name.present?
users = users.where(goal_id: goal_id) if goal_id.present?
return users
end
# searches/new.html.erb
<%= form_for @search do |s| %>
<div class="form-group">
<%= s.label :keywords %>
<%= s.text_field :keywords %>
</div>
<div class="form-group">
<%= s.label :exercise %>
<%= s.select :name, options_for_select(@s_names), include_blank: true %>
</div>
<div class="form-group">
<%= s.label :goals %>
<%= s.collection_select :goal_id, Goal.order(:name), :id, :name, include_blank: true %>
</div>
<%= s.submit "Search", class: "btn btn-primary" %>
<% end %>
# searches_controller.rb
class SearchesController < ApplicationController
def new
@search = Search.new
@s_names = Sport.uniq.pluck(:name)
@users = User.uniq.pluck(:name)
end
def create
@search = Search.create(search_params)
redirect_to @search
end
def show
@search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit(:keywords, :name, :goal_id)
end
end
然后我的架构供参考:
create_table "goals", force: :cascade do |t|
t.string "name"
t.integer "user_id"
t.index ["user_id"], name: "index_goals_on_user_id", using: :btree
end
create_table "searches", force: :cascade do |t|
t.string "keywords"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "goal_id"
t.index ["goal_id"], name: "index_searches_on_goal_id", using: :btree
end
create_table "sports", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sports_users", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "sport_id", null: false
t.index ["user_id", "sport_id"], name: "index_sports_users_on_user_id_and_sport_id", using: :btree
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.integer "movement_id"
t.integer "goal_id"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["goal_id"], name: "index_users_on_goal_id", using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "goals", "users"
end
对于大量凌乱的代码非常抱歉,但我现在只是绊倒自己而感到困惑。
提前谢谢你。
答案 0 :(得分:0)
我会改变
r = 1
到
users = users.where(goal_id: goal_id) if goal_id.present?
对于高级搜索,我最近使用了本文中提到的方法:http://www.justinweiss.com/articles/search-and-filter-rails-models-without-bloating-your-controller/,如果您考虑扩展搜索选项,我认为值得一读。
编辑:以下评论中的完整回复
需要删除users = users.joins(:goals).where(goals: {id: goal_id})