Ruby on rails Rails搜索有很多关系

Ruby on rails Rails搜索有很多关系,ruby-on-rails,activerecord,devise,Ruby On Rails,Activerecord,Devise,嗨。我一直在想办法,但我被困太久了,感觉越来越痛 我正在尝试做一个高级搜索表单,允许您根据其他型号中的设置搜索用户。e、 g.搜索一个名为Jim的用户,他不跑步,目标是减肥 我有三种型号: 用户(使用设备) 运动(多对多用户) 目标(用户有许多目标,目标属于用户) 到目前为止,我已经设法让它工作,这样我就可以在用户模型中搜索东西(如名称),也可以通过选择框搜索用户运动。我一直无法找到工作的是搜索用户目标,我不知道为什么 当只搜索目标而不搜索其他字段时,我得到的是“似乎没有人有这些偏好” 我曾

嗨。我一直在想办法,但我被困太久了,感觉越来越痛

我正在尝试做一个高级搜索表单,允许您根据其他型号中的设置搜索用户。e、 g.搜索一个名为Jim的用户,他不跑步,目标是减肥

我有三种型号:

  • 用户(使用设备)
  • 运动(多对多用户)
  • 目标(用户有许多目标,目标属于用户)
到目前为止,我已经设法让它工作,这样我就可以在用户模型中搜索东西(如名称),也可以通过选择框搜索用户运动。我一直无法找到工作的是搜索用户目标,我不知道为什么

当只搜索目标而不搜索其他字段时,我得到的是“似乎没有人有这些偏好”

我曾尝试使用与我的运动相同的代码,但没有成功(猜测是因为不同的关系?)

非常抱歉有这么多乱七八糟的代码,但我只是在这一点上绊倒了自己,弄糊涂了

提前非常感谢。

我想换一下

users = users.where(goal_id: goal_id) if goal_id.present?

对于高级搜索,我最近使用了本文中介绍的方法:如果您考虑扩展搜索选项,我认为值得一读

编辑:在下面的评论中给出完整的回复
:外键=>:需要删除目标id

感谢您的回复!在执行此操作时,我会遇到以下错误:“PG::UndefinedColumn:error:column goals.goal\u id不存在”。但是它就在我的数据库中。我检查了我的代码,它看起来像这样:
where(:goals=>{:id=>goal\u id})
,确切地说,这两种语法都应该是正确的。问题在于您的自定义外键。从两个型号中删除
:外键=>:目标id
。从您的迁移来看,似乎没有这样的列。表格目标的PK应仅为“id”,而不是“目标id”。它试图
SELECT*FROM users-internal-JOIN-goals.goal\u id=users.id
,但没有意义。通过删除这些外键子句,rails将知道它应该在表goals中查找用户id。为连接生成的SQL应该看起来
SELECT*FROM users-internal-JOIN-goals ON-goals.user\u id=users.id
非常感谢!我只是在兜圈子,把我的代码弄得越来越乱。它现在起作用了。当它像这样结束时,真的很难弄清楚到底出了什么问题,哈哈。感谢您,现在将其标记为答案:)太好了,很乐意帮助:)。关于RoR,您必须记住的是,战斗约定总是导致伤亡,指定自定义外键是违反RoR约定的事情之一(至少在简单关系中,同一表的多个关系需要不同的方法)。
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
users = users.where(goal_id: goal_id) if goal_id.present?
users = users.joins(:goals).where(goals: {id: goal_id})