ActiveRecord查询无效

时间:2015-09-24 00:19:13

标签: ruby-on-rails ruby activerecord

Rails 4,SQLite3。

我一直在清理我的查询,试图摆脱使用ruby来处理结果。所以我替换了这个(工作正常):

 @players = Player.all.select { |m| m.team == nil}.sort_by{ |x| [x.position, x.surname] }

用这个:

@players = Player.where(team:nil).order(position :: asc,surname :: asc)

它不起作用。具体来说,.where(team:nill)不会过滤掉已经被选中的玩家。我得到了所有的球员。 .order部分工作正常。

我在视图中添加了一个if语句,以查看player.team == nil是否已经被选中,并且确实如此。换句话说,以下正确地将“它为空!”在已经被选中的球员旁边:

  <% @players.each do |player| %>
   <tr>
   <% if player.team == nil %>
   <td> its null!</td>
   <%else%>
   <%end%> 

  <td><td><%= player.first_name %> <%= player.surname %></td></td>
  <td><%= player.position %></td>
   </tr>
  <% end %>

那么为什么我的查询不会过滤掉它们呢?

生成的查询是:

SELECT "players".* FROM "players" WHERE "players"."team_id" IS NULL  ORDER BY "players"."position" ASC, "players"."surname" ASC  

以下是我的模特:

 class Player < ActiveRecord::Base
 has_one :team, through: :ownership
 has_one :ownership

 validates :first_name, presence: true
 validates :surname, presence: true
 validates :position, presence: true

 def full_name
 "#{first_name} #{surname}"
 end
 end

 class Team < ActiveRecord::Base
 has_many :ownerships
 has_many :players, through: :ownerships

 validates :name, presence: true

 validates :division, presence: true
 end

 class Ownership < ActiveRecord::Base
 belongs_to :player
 belongs_to :team

 validates :round, :pick, :team_id, presence: true
 end

这是架构:

 ActiveRecord::Schema.define(version: 20150923185333) do

 create_table "ownerships", force: :cascade do |t|
t.integer  "round"
t.integer  "pick"
t.integer  "team_id"
t.integer  "player_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

add_index "ownerships", ["player_id"], name:  "index_ownerships_on_player_id"
add_index "ownerships", ["team_id"], name: "index_ownerships_on_team_id"

create_table "players", force: :cascade do |t|
t.string   "first_name"
t.string   "position"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string   "surname"
t.integer  "team_id"
end

create_table "teams", force: :cascade do |t|
t.string   "name"
t.string   "division"
t.datetime "created_at",        null: false
t.datetime "updated_at",        null: false
t.string   "logo_file_name"
t.string   "logo_content_type"
t.integer  "logo_file_size"
t.datetime "logo_updated_at"
end

end

1 个答案:

答案 0 :(得分:1)

如果查看查询生成的SQL,可能包含以下内容:

SELECT players.* WHERE players.team_id IS NULL

如果<{em> team是通过belongs_to :team上的Player关联定义的,那么可以正常工作,但不是:它通过has_one :team定义一个through: :ownership选项。这意味着您需要通过teams表加入ownership表,并选择没有关联teams记录的记录。由于您需要使用左连接,您必须手动编写连接&#34;:

@players = Player.joins("LEFT OUTER JOIN ownerships ON ownerships.player_id = players.id")
  .joins("LEFT OUTER JOIN teams ON ownerships.team_id = teams.id")
  .where("teams.id IS NULL").order(position: :asc, surname: :asc)

您可能希望删除无关的列team_id以避免这种混淆:

remove_column :players, :team_id