いくつかの異なるクライアントに広告を配信するWebサービスがあります。広告の構造はクライアントによって異なるため、モデルとコントローラーの名前空間をクライアント名で使用して、広告を区別しています。高レベルから見ると、次のようになります。
'app/models/client1/ad.rb'
class Client1::Ad < ActiveRecord::Base
attr_accessible :title, :description
end
'app/models/client2/ad.rb'
class Client2::Ad < ActiveRecord::Base
attr_accessible :title, :description, :source
end
実際には、これらのモデルはより複雑で関連性がありますが、それは重要ではありません。
rspec-Rails2.4.0とfactory_girl_Rails1.0.1を使用していくつかの単体テストを書いていますが、すべての工場がうまく機能しています。ただし、名前空間モデルのファクトリを定義できません。私は次のようなことを試しました:
Factory.define :client1_ad, :class => Client1::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
end
そして
Factory.define :client2_ad, :class => Client2::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
ad.source "feed"
end
それは仕事をしませんでした。私は周りを見回しましたが、私が見たすべての例は、名前空間のないモデルを使用していました。誰かアイデアはありますか?どんな入力でも大歓迎です。
ここに最小限の実例があります。問題がどこにあるかを特定するために使用できるかもしれません。 dmarkowの回答に残したコメントは、どこか別の場所にエラーがあることを示唆しています。
app/models/bar/foo.rb
class Bar::Foo < ActiveRecord::Base
end
* db/migrate/20110614204536_foo.rb *
class Foo < ActiveRecord::Migration
def self.up
create_table :foos do |t|
t.string :name
end
end
def self.down
drop_table :foos
end
end
spec/factorys.rb
Factory.define :foo, :class => Bar::Foo do |f|
f.name 'Foooo'
end
* spec/models/foo_spec.rb *
require 'spec_helper'
describe Bar::Foo do
it 'does foo' do
foo = Factory(:foo)
foo.name.should == 'Foooo'
end
end
テストの実行:
$ rake db:migrate
$ rake db:test:prepare
$ rspec spec/models/foo_spec.rb
.
Finished in 0.00977 seconds
1 example, 0 failures
それが役に立てば幸い。
この回答が投稿されてから、FactoryGirlが変わったのではないかと思います。私はそれを機能させるためにやった
Factory.define do
factory :foo, :class => Bar::Foo do |f|
f.name 'Foooo'
end
end
FactoryGirl
(4.5.)の現在の最新バージョンでは、次の構文が使用されます。
FactoryGirl.define do
factory :client1_ad, class: Client1::Ad do |f|
f.title "software tester"
f.description "Immediate opening"
end
end
client1_ad
は、任意の名前にすることができます。cozは、すでにそのクラス名を識別します。
私はこの質問がFactoryGirlに関連する問題を調べているのを見つけ、ソースを少し読んだ後、工場の名前を変更することで問題を解決できることがわかりました。
モジュール内で名前空間が付けられたモデルクラスがある場合、例:_Admin::User
_次のようにファクトリを定義する必要がありました。
_factory :'admin/user', class: Admin::User do
#...
end
_
のではなく:
_factory :admin_user, class: Admin::User do
#...
end
_
たぶん、このちょっとした情報がいつか誰かを助けるかもしれません。私の問題の詳細は、build(described_class)
を使用してRSpec
仕様のファクトリからインスタンスを構築しようとしたことでした。これは、名前空間のないクラスでは問題なく機能しますが、モジュール内のクラスでは機能しません。その理由は、ファクトリを検索するときに、FactoryGirlがActiveSupport
のunderscore
ヘルパーを使用してファクトリ名を正規化するためです。
クラス名の文字列ではなく、実際のクラスを渡してみましたか?
Factory.define :client1_ad, :class => Client1::Ad do |ad|