5

W app/services mam kilka klas, jako Notification::Finder i Notification::Builder.autoload_paths nie zna przestrzeni nazw?

Są one umieszczane jako app/services/notification/builder.rb i app/services/notification/finder.rb.

Istnieje również klasa Notification jako model, w app/models/notification.rb

autoload_path jest skonfigurowany jak w config.autoload_paths += %W(#{config.root}/app/services)

Kiedy próbuję załadować Finder, to działa:

Loading development environment (Rails 3.2.9) 
[1] pry(main)> Notification::Finder 
=> Notification::Finder 

Ale kiedy Próbuję Builder, pojawia się problem z automatycznym ładowaniem szyn:

Loading development environment (Rails 3.2.9) 
[1] pry(main)> Notification::Builder 
=> ActiveRecord::Associations::Builder 

Po prostu ignoruje przestrzeń nazw, której użyłem, gdy stała nazwa (Builder) została już zdefiniowana przez inną przestrzeń nazw i otrzymuje zamiast niej ActiveRecord::Associations::Builder.

Czy jest to oczekiwane zachowanie, czy błąd szyny?

Idąc bardziej szczegółowy, metoda const_missing na activesupport/dependencies.rb otrzyma const_name 'Builder' i nesting.inspect => 'nil'.

Ciekawy że kiedy używam constantize, to rozwiązuje zgodnie z oczekiwaniami:

Loading development environment (Rails 3.2.9) 
[1] pry(main)> 'Notification::Builder'.constantize 
=> Notification::Builder 

(szyny problem na github: https://github.com/rails/rails/issues/8726)

+1

Czy to możliwe, że 'Builder' jest zastrzeżoną nazwą? – tadman

+2

@adadman to nie jest =/ –

+1

czy można go odtworzyć w świeżej aplikacji? Jeśli tak, proszę załóż jeden z nich na github i daj mi znać. Spojrzę na to. Istnieją sytuacje, w których mechanizm ładujący szyny nie będzie w stanie zwrócić prawidłowego wyniku. Myślę, że to powinno być możliwe ... –

Odpowiedz

2

ActiveRecord :: Związki :: Builder jest moduł w Rails. Jeśli masz Notification :: Builder, można zadać mu swoją klasę:

>> Notification::Builder 
=> ActiveRecord::Associations::Builder 
>> Notification::Builder.class 
=> Module 
>> Notification::Builder.ancestors 
=> [ActiveRecord::Associations::Builder] 

Jest to oczekiwane zachowanie?

Tak

OK, więc ... co wybory masz?

  • Możesz użyć innego terminu niż Builder. Jak fabryka. lub Zawiadomienie :: NotificationBuilder

Więcej informacji:
* http://www.rubydoc.info/docs/rails/3.1.1/ActiveRecord/Associations/Builder/Association
* http://apidock.com/rails/ActiveRecord/Associations/Builder

1

Ten problem występuje, ponieważ używasz modelu ActiveRecord jako nazw. Stworzyłem sedno z eksperymentami, dopóki nie zobaczyłem głównej przyczyny. Modele

ActiveRecord obejmują moduł ActiveRecord::Associations.Ponieważ można uzyskać stałą wartość dodając moduł, stałą Builder zdefiniowaną w ramach Associations można teraz również uzyskać za pośrednictwem modelu AR. Dostaniesz to zachowanie z każdej klasy określonej w modułach, które są zawarte w modelu AR:

1.9.3-p194 :010 > Post.ancestors 
=> [Post(id: integer, title: string, published_at: datetime, created_at: datetime, updated_at: datetime), Post::GeneratedFeatureMethods, #<Module:0x007fec74dc33a0>, ActiveRecord::Base, ActiveRecord::Core, ActiveRecord::Store, ActiveRecord::Serialization, ActiveModel::Serializers::Xml, ActiveModel::Serializers::JSON, ActiveModel::Serialization, ActiveRecord::Reflection, ActiveRecord::Transactions, ActiveRecord::Aggregations, ActiveRecord::NestedAttributes, ActiveRecord::AutosaveAssociation, ActiveModel::SecurePassword, ActiveRecord::Associations, ActiveRecord::Timestamp, ActiveModel::Validations::Callbacks, ActiveRecord::Callbacks, ActiveRecord::AttributeMethods::Serialization, ActiveRecord::AttributeMethods::Dirty, ActiveModel::Dirty, ActiveRecord::AttributeMethods::TimeZoneConversion, ActiveRecord::AttributeMethods::PrimaryKey, ActiveRecord::AttributeMethods::Query, ActiveRecord::AttributeMethods::BeforeTypeCast, ActiveRecord::AttributeMethods::Write, ActiveRecord::AttributeMethods::Read, ActiveRecord::AttributeMethods, ActiveModel::AttributeMethods, ActiveRecord::Locking::Pessimistic, ActiveRecord::Locking::Optimistic, ActiveRecord::CounterCache, ActiveRecord::Validations, ActiveModel::Validations::HelperMethods, ActiveSupport::Callbacks, ActiveModel::Validations, ActiveRecord::Integration, ActiveModel::Conversion, ActiveRecord::AttributeAssignment, ActiveModel::ForbiddenAttributesProtection, ActiveModel::DeprecatedMassAssignmentSecurity, ActiveRecord::Sanitization, ActiveRecord::Scoping::Named, ActiveRecord::Scoping::Default, ActiveRecord::Scoping, ActiveRecord::Inheritance, ActiveRecord::ModelSchema, ActiveRecord::ReadonlyAttributes, ActiveRecord::Persistence, Object, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, V8::Conversion::Object, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject] 

Możliwym rozwiązaniem jest zastosowanie modułu jako nazw. Na przykład module Notifications.

Powiązane problemy