5

In app/services, ho alcune classi, come Notification::Finder e Notification::Builder.autoload_paths non è a conoscenza dello spazio dei nomi?

Sono posizionati come app/services/notification/builder.rb e app/services/notification/finder.rb.

C'è anche la classe Notification come modello, a app/models/notification.rb

L'autoload_path è configurato come in config.autoload_paths += %W(#{config.root}/app/services)

Quando provo a caricare Finder, funziona:

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

Ma quando Provo il Builder, ottengo un problema con il caricamento automatico dei binari:

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

Ignora semplicemente lo spazio dei nomi che ho usato quando il nome della costante (Builder) è già stato definito da un altro spazio dei nomi e ottiene invece il ActiveRecord::Associations::Builder.

È questo il comportamento previsto o un baco?

Andando più dettagliato, il metodo const_missing a activesupport/dependencies.rb riceve un const_name 'Builder' e nesting.inspect => 'nil'.

Curioso che quando uso constantize, si risolve come previsto:

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

(problema Rails a github: https://github.com/rails/rails/issues/8726)

+1

È possibile che 'Builder' sia un nome riservato? – tadman

+2

@tadman non è =/ –

+1

puoi riprodurlo in una nuova applicazione? Se è così, per favore mettine uno su github e fammi sapere. Darò un'occhiata. Ci sono situazioni in cui il caricatore automatico delle rotaie non sarà in grado di restituire il risultato corretto. Penso che questo dovrebbe essere possibile ... –

risposta

2

ActiveRecord :: :: Associazioni Builder è un modulo in Rails. Se si dispone di una Notificazione :: Builder, si può chiedere che la sua classe:

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

È questo il comportamento previsto?

OK, quindi ... quali scelte avete?

  • È possibile usare un termine diverso da quello del costruttore. Come fabbrica o notifica :: NotificationBuilder

Maggiori informazioni:
* http://www.rubydoc.info/docs/rails/3.1.1/ActiveRecord/Associations/Builder/Association
* http://apidock.com/rails/ActiveRecord/Associations/Builder

1

Questo problema esiste perché si sta utilizzando un modello di ActiveRecord come uno spazio dei nomi. Ho creato un senso con alcuni esperimenti fino a quando ho visto la causa principale.

ActiveRecord modelli includono il modulo ActiveRecord::Associations.Poiché è possibile ottenere una costante quando si include un modulo, la costante Builder definita all'interno di Associations è ora raggiungibile anche tramite il modello AR. Otterrete questo comportamento con ogni classe definita nei moduli, che sono incluse in un modello 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] 

Una possibile soluzione è quella di utilizzare un modulo come uno spazio dei nomi. Ad esempio module Notifications.

Problemi correlati