Канканкан Выберите поле

Я пытаюсь настроить поле объекта канканкан:

projectsAPI = Project.accessible_by(current_ability).select('projects.name, projects.price * 5 as new_price')
respond_to do |format|
      format.json { render :json => {
                                    :project_data => projectsAPI
                                    }
                   }

Проблема в том, что когда я проверяю результаты API, он просто возвращает все поля проекта без каких-либо вещей в выражении .select.

Когда я проверяю журнал, в запросе есть настраиваемые поля, но также есть и остальные поля из проектов.

Как я могу настроить поля в возврате json API объектов канканкана?


person GavinBelson    schedule 30.09.2017    source источник


Ответы (1)


Как выглядит .to_sql?

Вы пробовали что-то подобное с подзапросом? Именно так я часто решаю проблемы CanCan в отношении соединений, которые он делает.

projectsAPI = Project.where("projects.id IN (?)", Project.accessible_by(current_ability).select(:id).to_sql).select('projects.name, projects.price * 5 as new_price')
person kaspernj    schedule 30.09.2017
comment
Выдает ошибку, поскольку все еще выбирает все поля в подзапросе. Если зарегистрировать Project.accessible_by(current_ability).select(:id).to_sql, он отображает SELECT "projects"."id", "projects"."id" AS t0_r0, "projects"."name"... так что в основном .select(:id) выбирает id, а затем все поля в объекте в любом случае - person GavinBelson; 30.09.2017
comment
Мне удалось заставить ваше предложение работать с использованием .pluck(:id) в подзапросе. Однако подзапрос менее эффективен, чем просто выбор нужных столбцов. Есть ли другой способ, кроме .select, чтобы получить настраиваемые поля из активной записи? - person GavinBelson; 30.09.2017
comment
Я бы не стал выщипывать, потому что сначала будут извлечены все идентификаторы в отдельный запрос, и это может привести к сбою, если будет возвращено много идентификаторов. Причина, по которой CanCan выбирает больше полей, заключается в том, что он использует .includes(...).references(...) вместо .left_joins(...). Он не может выполнить .left_joins(...), потому что кеш соединений не используется совместно с включениями. Я считаю, что в CanCanCan и Rails есть проблемы с обеими вещами. Я обновлю свой комментарий, как только найду их. - person kaspernj; 02.10.2017
comment
Я понимаю вашу точку зрения о создании массива pluck ... но какой другой вариант есть? Выполнение подзапроса sql просто выбирает все поля и, похоже, не работает. - person GavinBelson; 02.10.2017
comment
Боюсь, вам и всем нам придется подождать, пока связанный PR для Rails не будет объединен и CanCanCan не изменится на left_joins вместо include.references. - person kaspernj; 02.10.2017
comment
Таким образом, .accessible_by(current_ability), похоже, работает с большинством объектов, которые у меня есть, как и ожидалось, он дает сбои только на .select, когда объект имеет столбец user_id. Вероятно, потому что cancancan пытается присоединиться к таблице пользователей.. Не уверен, что вы хотите добавить это в свои билеты. - person GavinBelson; 04.10.2017