我觉得我必须把这个放在这里:
:through
Specifies an association through which to perform the query. This can be any other type of association...
https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many.
我已经建立了模型,就像你展示的那样,工作得很好:
>> Member.first.user.user_accounts
=> #<ActiveRecord::Associations::CollectionProxy [#<UserAccount id: 1, user_id: 1>]>
# through: user
>> Member.first.user_accounts
Member Load (0.8ms) SELECT `members`.* FROM `members` ORDER BY `members`.`id` ASC LIMIT 1
UserAccount Load (0.9ms) SELECT `user_accounts`.* FROM `user_accounts` INNER JOIN `users` ON `user_accounts`.`user_id` = `users`.`id` WHERE `users`.`id` = 1 LIMIT 11
=> #<ActiveRecord::Associations::CollectionProxy [#<UserAccount id: 1, user_id: 1>]>
以下是我是如何打破它的:
class AddUsersToUserAccounts < ActiveRecord::Migration[5.1]
def change
add_column :user_accounts, :users, :integer
end
end
>> Member.first.user_accounts
Member Load (0.8ms) SELECT `members`.* FROM `members` ORDER BY `members`.`id` ASC LIMIT 1
UserAccount Load (0.7ms)
SELECT `user_accounts`.* FROM `user_accounts`
INNER JOIN `users` ON `user_accounts`.`user_id` = `users`.`id`
WHERE `user_accounts`.`users` = NULL LIMIT 11
# ^
# using `users` column instead
=> #<ActiveRecord::Associations::CollectionProxy []>
>> UserAccount.column_names
=> ["id", "user_id", "users"]
>> Member.first.user_accounts.arel.ast.cores[0].wheres[0].children[0].to_sql
=> "`user_accounts`.`users` = ?"
当构建users.id = 1
where子句时,arel获取散列{"users"=>{"id"=>1}}
并输出一些SQL.如果存在users
列,它会偶然发现这一部分,并将"users"
键视为列而不是表:
when value.is_a?(Hash) && !table.has_column?(column_name)
# ^^^^^^^^^ this one ^^^^^^^^^^^^
100
当我回滚并删除users
列时,它进入正确的分支并构建一个工作的SQL:
>> UserAccount.column_names
=> ["id", "user_id"]
>> Member.first.user_accounts.arel.ast.cores[0].wheres[0].children[0].to_sql
=> "`users`.`id` = ?"