Полиморфные Запросы Таблицы Отношений в Rails - найти объект по нескольким

У меня есть таблица отношений в приложении рельсы под названием edit_privileges, в котором User "редактор" и ряд других классов "редактируемые". Скажем, два из этих классов Message а также Comment,

мой EditPrivilege Модель использует следующий код:

belongs_to :editor, :class_name => "User"
belongs_to :editable, :polymorphic => true

А также User, конечно

has_many :edit_privileges, :foreign_key => "editor_id"

Чтобы определить, есть ли у пользователя права на редактирование для определенной модели, я не могу выполнить обычный запрос:

user.edit_privileges.find_by_editable_id(@message.id)

потому что, если у пользователя есть права на редактирование комментария с тем же идентификатором, что и @messageзапрос вернет истину с неверной записью прав на редактирование из таблицы.

Итак, я попытался сделать эти варианты:

user.edit_privileges.find(:all, :conditions => ["editable_id = ? AND editable_type ?", @message.id, @message.class.to_s])
user.edit_privileges.where(:editable_id => @message.id, :editable_type => @message.class.to_s)

который отлично работает при поиске нужной записи, но возвращает массив вместо объекта (пустой массив [] если нет прав на редактирование). Это особенно проблематично, если я пытаюсь создать метод уничтожения прав на редактирование, поскольку вы не можете передать .destroy на массиве.

Я фигура дополняет .first к двум вышеупомянутым решениям возвращается первый объект и nil если результат запроса пустой, но действительно ли это лучший способ сделать это? Есть ли проблемы с этим? (например, вместо использования динамических искателей на основе атрибутов, таких как find_by_editabe_id_and_editable_type)

1 ответ

Решение

Использование find(:first, ...) вместо find(:all, ...) чтобы получить одну запись (обратите внимание, что она может вернуть nil, в то время как find вызовет исключение RecordNotFound). Итак, для вашего примера:

user.edit_privileges.find(:first, :conditions => { :editable_id => @message.id, :editable_type => @message.class.to_s })

Кстати, если вы находитесь на более краевых рельсах версии (3.x), Model.where(...).first это новый синтаксис:

user.edit_privileges.where(:editable_id => @message.id, :editable_type => @message.class.to_s).first
Другие вопросы по тегам