5

には、asと。app/servicesのクラスがいくつかあります。Notification::FinderNotification::Builder

それらはととして配置されapp/services/notification/builder.rbますapp/services/notification/finder.rb

Notificationモデルとしてのクラスもあります。app/models/notification.rb

autoload_pathは次のように構成されますconfig.autoload_paths += %W(#{config.root}/app/services)

ロードしようとするとFinder、次のように機能します。

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

しかし、を試してみるBuilderと、レールの自動読み込みで問題が発生します。

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

定数名(Builder)が他の名前空間によってすでに定義されている場合に使用した名前空間を無視し、ActiveRecord::Associations::Builder代わりに取得します。

これは予想される動作ですか、それともレールのバグですか?

さらに詳しく説明すると、のconst_missingメソッドは、、およびをactivesupport/dependencies.rb受け取ります。const_name 'Builder'nesting.inspect => 'nil'

不思議なことに、constantizeを使用すると、期待どおりに解決されます。

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

(githubでのRailsの問題:https ://github.com/rails/rails/issues/8726 )

4

2 に答える 2

2

ActiveRecord::Associations::Builder は Rails のモジュールです。Notification::Builder がある場合は、そのクラスを尋ねることができます:

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

これは予想される動作ですか?

はい

では、どのような選択肢がありますか?

  • Builder とは異なる用語を使用できます。ファクトリーのように。または Notification::NotificationBuilder

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

于 2013-01-03T18:04:46.593 に答える
1

この問題は、ActiveRecord モデルを名前空間として使用しているために発生します。根本的な原因がわかるまで、いくつかの実験を行って要点を作成しました。

ActiveRecordモデルにはActiveRecord::Associationsモジュールが含まれています。モジュールを含めるときに定数を取得できるため、内部でBuilder定義された定数にAssociationsも AR モデルを介して到達できるようになりました。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] 

考えられる解決策は、モジュールを名前空間として使用することです。たとえばmodule Notifications

于 2013-01-03T19:15:53.537 に答える