Skip to content

Instantly share code, notes, and snippets.

@steverandy
Created August 5, 2011 13:28
Show Gist options
  • Save steverandy/1127539 to your computer and use it in GitHub Desktop.
Save steverandy/1127539 to your computer and use it in GitHub Desktop.
def set_position
if not self.special
categories = self.user.categories.normal.with_position.asc(:position)
if categories.present? && categories.count > 0
self.position = categories.last.position + 1
else
self.position = 1
end
end
end
@paulelliott
Copy link

Did you set inverse_of on the relation?

@steverandy
Copy link
Author

steverandy commented Aug 5, 2011 via email

@paulelliott
Copy link

paulelliott commented Aug 5, 2011 via email

@steverandy
Copy link
Author

Sorry it did actually have inverse_of.

class User
  include Mongoid::Document
  include Mongoid::Timestamps

  embeds_many :categories, :validate => false
end

class Category
  include Mongoid::Document
  include Mongoid::Timestamps

  embedded_in :user, :inverse_of => :categories
end

The error was the following

NoMethodError: undefined method `categories' for nil:NilClass

The methods was called from self.user.categories.normal.with_position.asc(:position) from the following codes.

def set_position
  if not self.special
    categories = self.user.categories.normal.with_position.asc(:position)
    if categories.present? && categories.count > 0
      self.position = categories.last.position + 1
    else
      self.position = 1
    end
  end
end

@paulelliott
Copy link

Where is the set_position method? Is it in the category?

Can you post the fabricators being used in here as well?

@steverandy
Copy link
Author

class Category
  include Mongoid::Document
  include Mongoid::Timestamps

  embedded_in :user, :inverse_of => :categories

  before_create :set_position

  def set_position
    if not self.special
      categories = self.user.categories.normal.with_position.asc(:position)
      if categories.present? && categories.count > 0
        self.position = categories.last.position + 1
      else
        self.position = 1
      end
    end
  end
end

For the fabricator:

Fabricator(:category) do
  title { Fabricate.sequence(:title) { |i| "Category #{i}" } }
end

Fabricator(:user) do
  full_name { Fabricate.sequence(:full_name) { |i| "User #{i}" } }
  username { Fabricate.sequence(:username) { |i| "user#{i}" } }
  email { Fabricate.sequence(:email) { |i| "user#{i}@example.com" } }
  password "password"
  password_confirmation "password"
end

And the unit test

  test "should have position" do
    user = Fabricate :user
    category = Fabricate :category, :user => user, :title => "Category"
    assert_equal category.position, 1
  end

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