Как связаны запросы 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
Но как эти вещи даже связаны и почему я могу делать запросы одним способом, а другим - нет?
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?
Который просто заявляет, что я ошибся в написании принадлежащего к моей таблице соединений.
AR ожидает, что будет определено имя ассоциации, а не таблица в базе данных.
Так меняется
# (STI) table users, but AR model is called SalesRepresentative
belongs_to :user, class_name: ::SalesRepresentative
в
# changed to real AR table name passing the foreign_key
belongs_to :sales_representative, class_name: ::SalesRepresentative, foreign_key: :user_id
заставил это работать как ожидалось.