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
答案 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