ActiveRecord::StatementInvalid PG::UndefinedColumn: ОШИБКА

Я использую rails_admin для панели администратора. Просто измените ассоциацию в модели изображения

Из этого

class Image < ApplicationRecord
   belongs_to :user 
   belongs_to :product 
end

к этому

class Image < ApplicationRecord
   has_one :user 
   has_one :product 
end

и модель пользователя

class User < ApplicationRecord
   has_many :images,dependent: :destroy
end

Получаю эту ошибку, когда пытаюсь изменить пользователя из панели администратора. С другой стороны все работает нормально.

ActiveRecord::StatementInvalid at /user/72/edit

PG::UndefinedColumn: ERROR:  column users.image_id does not exist
LINE 1: SELECT  "users".* FROM "users" WHERE "users"."image_id" = $1...
                                         ^
: SELECT  "users".* FROM "users" WHERE "users"."image_id" = $1 LIMIT $2

person t s    schedule 01.02.2017    source источник


Ответы (1)


У Rails отличная документация. В документации для has_one здесь указано, что "Этот метод следует использовать только в том случае, если другой класс содержит внешний ключ», поэтому он ищет внешний ключ image_id в записи user. Вы бы создали это с помощью миграции; см. этот сообщение о переполнении стека для получения дополнительной информации о внешних ключах и миграции.

Но прежде чем зайти так далеко, подумайте:

  • Зачем вообще менять отношение Image с belongs_to :user на has_one :user? Чтобы свести к минимуму ассоциации SQL и то, как Rails отображает их, если пользователь has_many :images, то изображения обязательно должны быть belong_to пользователем; они являются противоположными сторонами отношения, за исключением отношения has_and_belongs_to_many. Если A принадлежит B, то B имеет один (или несколько) из A. Я настоятельно рекомендую вам сохранить изображения как имеющие отношения belongs_to, в то время как Пользователь и Продукт могут have_many изображений. Чтобы объяснить, почему это имеет смысл: у пользователя могут быть фотографии профиля с изображением их лица, дома и т. д. (has_many :images). Продукт (обувь) может иметь несколько изображений одной и той же обуви (has_many :images), но очень маловероятно, что конкретное изображение обуви будет отображаться как на пользователя, так и на продукт.
  • Я настоятельно рекомендую вам управлять изображениями и вложениями с помощью таких драгоценных камней, как attachinary или скрепка. Если вы работаете с загруженными файловыми вложениями, такие библиотеки избавят вас от головной боли в будущем, когда дело доходит до изменения размера, сжатия изображений и т. д. Я уверен, что ваше направление в попытке изменить отношение было информировано некоторыми из проблем, которые эти драгоценные камни решат для вас.
person quetzaluz    schedule 02.02.2017
comment
Я понимаю ваше объяснение, но я использую одну таблицу изображений как для пользователя, так и для продукта. Изображение пользователя сохраняется во время new_user и edit_user и так же, как и для продукта. пользователь может иметь максимум 3 изображения. пользователь и продукт не имеют прямого отношения, это похоже на этот user->store->products. Но когда я использую own_to как для пользователя, так и для продукта, их идентификаторы требуются в таблице изображений, что мне не нужно. если пользователь сохраняет изображение, то в таблице изображений product_id имеет значение null и наоборот, и этого не происходит в случае принадлежности_к . - person t s; 02.02.2017
comment
Это имеет смысл, и одна таблица изображений — хороший дизайн; в этом случае вам может понадобиться таблица пересечений, в которой столбцы entity, entity_id, image_id Entity будут именем класса и идентификатором, поэтому строка будет выглядеть примерно так: User, 1, 2, где 1 — user_id, а 2 — image_id. . Я снова рекомендую вам использовать что-то вроде Attachinary, которое сделает всю эту настройку за вас. - person quetzaluz; 02.02.2017
comment
Еще одно замечание по этому поводу: для has_many также потребуется объявление through:. Подробнее об этом здесь: guides.rubyonrails.org/ - person quetzaluz; 02.02.2017
comment
Я использую скрепку для загрузки изображений и обновил свой предыдущий комментарий. - person t s; 02.02.2017
comment
Потрясающий! В этом руководстве рассказывается, как использовать скрепку для этого колодца: С практической точки зрения, пользователь и продукт должны иметь ` has_attached_file :image`, и вы должны быть установлены - person quetzaluz; 02.02.2017
comment
Я надеялся, что это помогло, поскольку моей главной целью было дать быстрый ответ после вашего первоначального сообщения; если это не так, надеюсь, другие ответы могут помочь. - person quetzaluz; 02.02.2017
comment
Небольшой трюк с rails 5 class Image < ApplicationRecord belongs_to :user belongs_to :product, optional: true end Он у меня работает, и спасибо за вашу помощь. - person t s; 02.02.2017