Как связаны запросы I18n и базы данных ActiveRecord?

Кто-нибудь знает, какое отношение I18n имеет к базе данных?

class DecorativeCentersSalesRepresentative < ActiveRecord::Base
  belongs_to :decorative_center, class_name: ::DecorativeCenter
  belongs_to :user, class_name: ::SalesRepresentative
end

class DecorativeCenter < ActiveRecord::Base
  has_many :decorative_centers_sales_representative
  has_many :sales_representatives,
    through: :decorative_centers_sales_representative
end

class SalesRepresentative < User
  has_many :decorative_centers_sales_representative,
    foreign_key: :user_id
  has_many :decorative_centers,
    through: :decorative_centers_sales_representative,
    foreign_key: :user_id
end

Все хорошо, и я могу сделать

SalesRepresentative.last.decorative_centers
  SalesRepresentative Load (0.7ms)  SELECT  `users`.* FROM `users` WHERE `users`.`type` IN ('SalesRepresentative')  ORDER BY `users`.`id` DESC LIMIT 1
  DecorativeCenter Load (0.3ms)  SELECT `decorative_centers`.* FROM `decorative_centers` INNER JOIN `decorative_centers_sales_representative` ON `decorative_centers`.`id` = `decorative_centers_sales_representative`.`decorative_center_id` WHERE `decorative_centers_sales_representative`.`user_id` = 4
#=> [#<DecorativeCenter:0x000000088e5578]

Но когда я сделаю

DecorativeCenter.last.sales_representatives
  DecorativeCenter Load (0.2ms)  SELECT  `decorative_centers`.* FROM `decorative_centers`  ORDER BY `decorative_centers`.`id` DESC LIMIT 1
#=> I18n::InvalidLocale: :en is not a valid locale
#=> from /home/andreydeineko/.rvm/gems/ruby-2.3.0@profill-base/gems/i18n-0.7.0/lib/i18n.rb:284:in `enforce_available_locales!'

ПОЧЕМУ??

Я знаю, что это недопустимая локаль, допустимая :pl:

I18n.available_locales
#=> [:pl]
I18n.default_locale
#=> :pl

Но как эти вещи вообще связаны и почему я могу запросить одним способом, а не другим?


person Andrey Deineko    schedule 26.01.2016    source источник
comment
Модуль Rails I18n на самом деле не имеет ничего общего с базой данных - скорее у вас есть что-то, что вызывает поиск при инициализации ActiveRecord::Collection. Однако невозможно сказать, почему без трассировки стека.   -  person max    schedule 26.01.2016
comment
@max обновил вопрос реальным кодом, спасибо за внимание   -  person Andrey Deineko    schedule 26.01.2016
comment
@AndreyDeineko - Вы получаете эти ошибки в консоли? Если это так, это может быть связано с методом проверки.   -  person BroiSatse    schedule 26.01.2016
comment
Единственная очевидная вещь, которую я вижу, это то, что has_many :decorative_centers_sales_representative не имеет правильного множественного числа. Используйте decorative_centers_sales_representatives.   -  person max    schedule 26.01.2016
comment
@BroiSatse Да, эти методы из консоли   -  person Andrey Deineko    schedule 26.01.2016
comment
@max это не должно быть причиной, мы решили назвать таблицу соединений по-деловому. Я мог бы попробовать изменить имя, но это не имеет значения   -  person Andrey Deineko    schedule 26.01.2016
comment
@AndreyDeineko - Попробуйте запустить DecorativeCenter.last.sales_representatives && nil - это предотвратит вызов проверки полученного объекта. Если нет исключений, вы знаете, что причиной проблемы является inspect. У вас есть больше трассировки стека?   -  person BroiSatse    schedule 26.01.2016
comment
@BroiSatse, к сожалению, та же ошибка ..   -  person Andrey Deineko    schedule 26.01.2016
comment
@AndreyDeineko - у тебя есть еще трассировка стека?   -  person BroiSatse    schedule 26.01.2016
comment
Хотел бы я иметь .. Единственное, что у меня есть, это то, что я опубликовал   -  person Andrey Deineko    schedule 26.01.2016
comment
Я бы исправил множественное число, если вам не нужно работать с устаревшей базой данных - вы получите кучу проблем с постоянным поиском, если не настроите специальное перегибание.   -  person max    schedule 26.01.2016
comment
@max изменился, но, к сожалению, безрезультатно..   -  person Andrey Deineko    schedule 26.01.2016
comment
@AndreyDeineko - Интересно. Это будет означать, что при построении отношения произойдет сбой, так как команда даже не отправится в базу данных. Можете ли вы загрузить другую ассоциацию? DecorativeCenter.last.decorative_centers_sales_representative   -  person BroiSatse    schedule 26.01.2016
comment
@max да, это работает правильно. Я обнаружил проблему, потому что SalesRepresentative наследуется от User (STI), и мне пришлось указать class_name.   -  person Andrey Deineko    schedule 26.01.2016


Ответы (1)


После некоторого времени отладки я нашел реальную проблему.

Начиная с конца:

  class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
    def initialize(reflection = nil)
      if reflection
        through_reflection      = reflection.through_reflection
        source_reflection_names = reflection.source_reflection_names
        source_associations     = reflection.through_reflection.klass._reflections.keys
        super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
      else
        super("Could not find the source association(s).")
      end
    end
  end

В этой ошибке локали были жестко закодированы, и это :en, поэтому я даже не мог получить сообщение об ошибке.

1) В моем приложении :en не было в доступных локалях, поэтому, чтобы получить сообщение об ошибке, которое Rails пытался выплюнуть, я временно установил локаль приложения на :en.

2) Теперь я мог получить ошибку:

ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) "sales_representative" or :sales_representatives in model DecorativeCentersSalesRepresentatives. Try 'has_many :sales_representatives, :through => :decorative_centers_sales_representatives, :source => <name>'. Is it one of versions, decorative_center, or user?

Что просто говорит о том, что я ошибся, написав в свою таблицу join_to.

AR ожидает, что будет определено имя ассоциации, а не таблицы в базе данных.

Так меняется

# (STI) table users, but AR model is called SalesRepresentative 
belongs_to :user, class_name: ::SalesRepresentative

to

# changed to real AR table name passing the foreign_key
belongs_to :sales_representative, class_name: ::SalesRepresentative, foreign_key: :user_id 

заставил это работать, как ожидалось.

person Andrey Deineko    schedule 26.01.2016
comment
Хорошо, однако вы обычно используете строку для имени класса, а не сам класс. class_name: "DecorativeCenter::SalesRepresentative". stackoverflow.com/questions/20390991/ - person max; 26.01.2016
comment
Как это вызвало проблему I18n? - person BroiSatse; 27.01.2016
comment
@BroiSatse, на самом деле это решение работало только один день, и почему-то оно не работало позже, поэтому мне пришлось сильно отлаживать (э-э) :) Я обновлю ответ реальным решением. - person Andrey Deineko; 28.01.2016