Skip to content

Instantly share code, notes, and snippets.

@codespectator
Created March 22, 2011 14:38
Show Gist options
  • Save codespectator/881304 to your computer and use it in GitHub Desktop.
Save codespectator/881304 to your computer and use it in GitHub Desktop.
# Unit test
test "should create record" do
plan = Fabricate(:free_plan)
account = Fabricate(:account, :agents => [ Fabricate.build(:agent) ])
Fabricate.build(:free_subscription, :plan => plan, :account => account)
assert account.valid?, "Account was invalid\n#{account.errors.to_yaml}"
end
# Fabricators
Fabricator(:account) do
company_name 'Example'
subdomain 'example'
end
Fabricator(:agent) do
forename 'James'
surname 'MacLeod'
password 'password'
password_confirmation 'password'
username 'james'
email_address 'james@example.co.uk'
end
Fabricator(:free_subscription, :from => :subscription) do
coupon_verified false
started_at Time.now
end
Fabricator(:free_plan, :from => :plan) do
plan_name 'Free'
cost 0
active_ticket_limit 2
agent_limit 1
company_limit 1
client_limit 1
sla_support false
report_support false
end
# Models
class Account
include Mongoid::Document
field :company_name, :type => String
field :subdomain, :type => String
field :joined_at, :type => DateTime
embeds_one :subscription
embeds_many :agents
embeds_many :issues
validates_presence_of :subdomain
validates_presence_of :company_name
validates_uniqueness_of :subdomain
validates_uniqueness_of :company_name
validates_presence_of :agents, :on => :create
#validates_presence_of :subscription, :on => :create
accepts_nested_attributes_for :agents
accepts_nested_attributes_for :subscription
before_create :set_joined_at_date
private
def set_joined_at_date
self.joined_at = Time.now
end
end
class Agent
include Mongoid::Document
field :forename, :type => String
field :surname, :type => String
field :username, :type => String
field :password_hash, :type => String
field :password_salt, :type => String
field :email_address, :type => String
embedded_in :account, :inverse_of => :agents
attr_accessor :password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :username
validates_uniqueness_of :username
end
class Subscription
include Mongoid::Document
field :coupon_verified, :type => Boolean
field :started_at, :type => DateTime
referenced_in :plan
embedded_in :account, :inverse_of => :subscription
end
class Plan
include Mongoid::Document
field :plan_name, :type => String
field :cost, :type => Integer
field :active_ticket_limit, :type => Integer
field :agent_limit, :type => Integer
field :company_limit, :type => Integer
field :client_limit, :type => Integer
field :sla_support, :type => Boolean
field :report_support, :type => Boolean
references_many :subscriptions
end
# And of course the error:
ERROR test_should_create_record (0.09s)
Mongoid::Errors::InvalidCollection: Access to the collection for Subscription is not allowed since it is an embedded document, please access a collection from the root document.
/Users/james/.rvm/gems/ruby-1.9.2-p0/gems/mongoid-2.0.0.rc.7/lib/mongoid/collections.rb:21:in `collection'
@paulelliott
Copy link

try this:

test "should create record" do
  plan = Fabricate(:free_plan)
  account = Fabricate(:account, :agents => [ Fabricate.build(:agent) ])
  Fabricate.build(:free_subscription, :plan => plan, :account => account)
  assert account.valid?, "Account was invalid\n#{account.errors.to_yaml}"
end

@codespectator
Copy link
Author

I can't do that as the subscription is an embedded document and it has to be created from the root document (the account) So I still get the error regarding the Subscription access etc

@paulelliott
Copy link

Actually, that is how they are supposed to work. I am using mongoid on a number of projects and do this all the time. If the root document is persisted, then you should then create the embedded by passing in the root as I did above.

You aren't validating that the account embeds a subscription, are you?

@codespectator
Copy link
Author

Yes I am, are the mongoid validations different because by default validates_associated will not validate the requirement for an association.

@paulelliott
Copy link

You should probably add a base subscription fabricator as well

Fabricator(:subscription) do
  account
end

Having that will save you headache in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment