5

app/services에는 Notification::FinderNotification::Builder과 같은 몇 가지 클래스가 있습니다.autoload_paths는 네임 스페이스를 인식하지 못합니까?

이들은 각각 app/services/notification/builder.rbapp/services/notification/finder.rb입니다. 내가 Finder를로드 할 때 app/models/notification.rb

autoload_path에서 모델로 Notification 클래스도 있습니다

config.autoload_paths += %W(#{config.root}/app/services)

같이 컨피그, 그것은 작동 :

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

그러나 때 을 시도하면 레일 로딩에 문제가 발생합니다.

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

상수 이름 (작성자)이 이미 다른 네임 스페이스에서 정의되었을 때 사용했던 네임 스페이스를 무시하고 대신 ActiveRecord::Associations::Builder을 가져옵니다.

예상되는 동작입니까, 레일 버그입니까? 상세한가는

, activesupport/dependencies.rb에서 const_missing 방법은 const_name 'Builder'nesting.inspect => 'nil'를 수신한다.

호기심 내가 constantize를 사용하는 경우, 그것은 예상대로 해결하는 것이 :

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

(레일 문제를 GitHub의에서 : https://github.com/rails/rails/issues/8726)

+1

'Builder'가 예약 된 이름 일 수 있습니까? – tadman

+2

@ tadman 아니에요/ –

+1

신선한 응용 프로그램에서 재현 할 수 있습니까? 그렇다면 github에 올려 놓고 알려주세요. 내가 한번 볼게. 레일 오토로더가 올바른 결과를 반환 할 수없는 경우가 있습니다. 나는 이것이 가능해야한다고 생각한다. –

답변

2

가 액티브 :: 협회 :: Builder는 레일에 모듈입니다. 당신은 알림이있는 경우 : 빌더, 당신은 동급를 요청할 수 있습니다 :

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

이 예상되는 행동인가?

OK, 그래서 ... 당신은 어떤 선택을해야합니까?

  • 빌더와 다른 용어를 사용할 수 있습니다. 공장처럼. 또는 알림 :: NotificationBuilder

상세 정보 : 네임 스페이스로 액티브 모델을 사용하고 있기 때문에이 문제가 존재
* http://www.rubydoc.info/docs/rails/3.1.1/ActiveRecord/Associations/Builder/Association
* http://apidock.com/rails/ActiveRecord/Associations/Builder

1

. 근본 원인을 발견 할 때까지 몇 가지 실험을 통해 요지를 만들었습니다.

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.

관련 문제