Это мой тест:Почему я не могу найти запись, которую я знаю, существует в моей тестовой сессии RSpec?
it "should return all relatives of a specific relation - e.g. 'sister'" do
u1 = create(:user)
ft = create(:family_tree, user: u1)
relation = "sister"
u2 = create(:user)
ft2 = create(:family_tree, user: u2)
membership = create(:membership, invited: u2, relation: relation, invited: u1, family_tree: ft)
expect(u1.relatives(relation).first.user.email).to eq u2.email
end
В командной строке, в частности, в РЕПЛ для Поддеть-спасательной, я могу найти успешный экземпляр этой membership
переменной, которая указывает на membership
записи:
[5] pry(#<RSpec::ExampleGroups::User>)> membership
=> #<Membership id: 13, family_tree_id: 106, user_id: 83, created_at: "2015-10-30 00:19:28", updated_at: "2015-10-30 00:19:28", relation: "sister", member_id: 13, connection_sent_at: nil, connection_responded_at: nil, connect_send_limit: nil, connect_times_sent: nil, connected: nil, connect_type: nil, request_status: nil, connection_removed_at: nil, invited_id: 81>
Однако, когда я пытаюсь найти эту конкретную запись через Membership.where...
, она возвращает пустой результат.
[12] pry(#<RSpec::ExampleGroups::User>)> Membership.where(user_id: '83')
=> []
[13] pry(#<RSpec::ExampleGroups::User>)> Membership.where(user_id: 83)
=> []
Для хорошей мерой, я попробовал поиск на другой атрибут family_tree_id
и я получил подобный nil
результат:
[14] pry(#<RSpec::ExampleGroups::User>)> Membership.where(family_tree_id: 106).first
=> nil
Несмотря на то, что локальная переменная membership
выше показывает наличие обоих этих записей.
Что может быть причиной этого?
Edit 1
Таким образом, после изучения SQL, я думаю, я нашел этот вопрос.
Это то, что мой has_many
в моей User
модели выглядит следующим образом:
has_many :memberships, ->(user){ where("memberships.user_id = :user_id OR memberships.invited_id = :user_id", user_id: user.id) }, dependent: :destroy
Это то, что SQL, который производит выглядит следующим образом:
[6] pry(main)> u2.memberships
Membership Load (0.4ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = $1 AND (memberships.user_id = 3 OR memberships.invited_id = 3) [["user_id", 3]]
=> []
Я считаю, что этот вопрос является первым AND
.. . Я думаю, что это связано с первым has_many :memberships
.
В этом случае, что должно произойти, оно ищет membership
записи с user_id=3
и ничего не находит, а затем он должен проверить membership.invited_id=3
и он должен найти что-то, так оно должно вернуть членство.
Как сменить этот первый AND
на OR
? Или как я могу исправить это в противном случае, если мое решение не является исправлением?
Edit 2
Целью membership
модели является то, что всякий раз, когда пользователь получает приглашен на генеалогическом древе другого пользователя ... что мы делаем, это создать членство для invited_user
на дереве inviter_user
. Таким образом, в основном мы используем эту модель membership
для управления разрешениями и доступа к генеалогическим деревьям разных пользователей.
Вот ассоциации между моделями:
User
has_one :family_tree, dependent: :destroy
has_many :memberships, ->(user){ where("memberships.user_id = :user_id OR memberships.invited_id = :user_id", user_id: user.id) }, dependent: :destroy
Family Tree
belongs_to :user
has_many :memberships, dependent: :destroy
has_many :members, through: :memberships, dependent: :destroy
Membership
belongs_to :family_tree
belongs_to :member
belongs_to :inviter, class_name: "User", foreign_key: "user_id"
belongs_to :invited, class_name: "User", foreign_key: "invited_id"
Member
has_many :memberships, dependent: :destroy
Для наглядности, когда вы вызываете PRY? Я предполагаю, что это в ожидании, но, пожалуйста, подтвердите. –
Во-вторых, вы проверили, вернулась ли транзакция? У вас есть две проблемы, которые я вижу: ваша родственная ассоциация может работать некорректно, и вы можете увидеть, как ваши транзакции БД возвращаются, прежде чем вы сможете их просмотреть. –
@RichardSeviora Я использую жуткий спасательный камень - https://github.com/ConradIrwin/pry-rescue - поэтому он автоматически останавливается всякий раз, когда появляется ошибка. Так что да, это происходит в ожидании. Не знаете, как проверить, откатилась ли транзакция. Как проверить это и отладить это? Я подозреваю, что вы можете быть правы, re: мои ассоциации ... но я использую этот процесс, чтобы помочь мне отлаживать и добираться туда. – marcamillion