Rails has_many: с помощью пользовательского foreign_key

#sql #ruby-on-rails #activerecord #has-many-through

#sql #ruby-on-rails #activerecord #имеет много сквозных

Вопрос:

У меня есть следующий набор моделей:

 class Cardstock < ActiveRecord::Base
  has_many :color_matches, :primary_key => :hex, :foreign_key => :hex
  has_many :palette_colors, :through => :color_matches
end

class ColorMatch < ActiveRecord::Base
  belongs_to :palette_color
  has_many :cardstocks, :foreign_key => :hex, :primary_key => :hex
end

class PaletteColor < ActiveRecord::Base
  has_many :color_matches
  has_many :cardstocks, :through => :color_matches
end
  

Вызов Cardstock.last.palette_colors выдает следующую ошибку:

 ActiveRecord::StatementInvalid: PGError: ERROR:  operator does not exist: character varying = integer
LINE 1: ...".palette_color_id    WHERE (("color_matches".hex = 66))  OR...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "palette_colors".* FROM "palette_colors"  INNER JOIN "color_matches" ON "palette_colors".id = "color_matches".palette_color_id    WHERE (("color_matches".hex = 66))  ORDER BY name ASC
  

Это показывает мне, что генерируемый ActiveRecord запрос использует идентификатор cardstock ( 66 ), где он должен использовать шестнадцатеричное значение cardstock ( bbbbaf ). Где-то мне нужно указать ActiveRecord, чтобы использовать hex столбец для соединения между cardstocks и color_matches . Поддерживает ли ActiveRecord это?

Комментарии:

1. Кстати, это Rails 2.3.x.

Ответ №1:

Все ваши отношения здесь не в порядке.

  • отношения между Cardstock и ColorMatch должны быть has_and_belongs_to_many отношениями с обеих сторон
  • везде, где у вас есть has_many relationship , вам нужна соответствующая belongs_to связь в соответствующем классе

Комментарии:

1. Это не совсем так. Нет абсолютно ничего плохого в использовании has_many :through вместо has_and_belongs_to_many ; Я считаю, что в наши дни это даже предпочтительный способ. Однако вы правы в том, что с отношениями что-то не так.

2. Спасибо, мне нужно изменить has_many вызов в ColorMatches на belongs_to . Но я думаю, что проблема не только в этом, потому что этот неверный запрос все еще генерируется.

Ответ №2:

Что-то не так с тем, как настроены ваши отношения. Я не совсем понимаю ваш конкретный вариант использования здесь, поэтому я не уверен, в чем проблема. Способ думать об этом, вероятно, заключается в соотношении «многие ко многим». Выясните, каковы две стороны этого «многие ко многим» и какова модель объединения. Я собираюсь привести пример, предполагающий, что ColorMatch — это ваша модель соединения — это то, что связывает палитру цветов с картоном. В этом случае вы захотите, чтобы ваши отношения выглядели примерно так:

 class Cardstock < ActiveRecord::Base
  has_many :color_matches, :primary_key => :hex, :foreign_key => :hex
  has_many :palette_colors, :through => :color_matches
end

class ColorMatch < ActiveRecord::Base
  belongs_to :palette_color
  belongs_to :cardstocks, :foreign_key => :hex, :primary_key => :hex
end

class PaletteColor < ActiveRecord::Base
  has_many :color_matches
  has_many :cardstocks, :through => :color_matches
end
  

С точки зрения вашей базы данных, у вас должны быть palette_color_id и hex поле в color_matches таблице и hex поле в cardstocks таблице.

Комментарии:

1. Точно! Однако, после настройки моих ассоциаций подобным образом, я все еще получаю ту же ошибку. Поддерживает ли ActiveRecord это? Или мне нужно настроить другую таблицу, только для hexes, на которую cardstocks и color_matches будут указывать целочисленные столбцы?