Michael Horojanski
Michael Horojanski

Reputation: 4711

Completed Active Record

I recieved task:

Add a method to the User model class called get completed count, which:

• accepts a user as a parameter

• determines the number of TodoItems the User has completed using an aggregate query function

– (Hint: You are looking for the count of TodoItems associated with a specific User where completed:true)

• returns the count

 class User < ActiveRecord::Base

     has_one :profile, dependent: :destroy
     has_many :todo_lists, dependent: :destroy
     has_many :todo_items, through: :todo_lists, source: :todo_items, dependent: :destroy
     validates :username, presence: true

     def get_completed_count
        todo_items.length
    end

  end

Does anyone can explain what is complete method does?

Thanks, Michael.

Upvotes: 1

Views: 657

Answers (5)

Venkata Reddy
Venkata Reddy

Reputation: 11

The below code worked for me.

def get_completed_count

self.todo_items.where(completed: true).count

end

Upvotes: 0

Payne
Payne

Reputation: 543

This is actually what I did this morning and it worked perfectly for me

def get_completed_count 
       todo_items.where(completed: true).count
end

Upvotes: 0

Michael Horojanski
Michael Horojanski

Reputation: 4711

The answer for me is:

def get_completed_count(user)
       user.todo_items.where(completed: true).count
end

Thanks to all for replies.

Upvotes: 0

Richard Peck
Richard Peck

Reputation: 76784

You'll want an ActiveRecordAssociation Extension:

#app/model/user.rb
class User < ActiveRecord::Base
   has_many :todo_items, through: :todo_lists, source: :todo_items, dependent: :destroy do
      def completed
         where(completed: true).count
      end
   end
end

This will allow you to call:

@user = User.find params[:id]
@user.todo_items.completed #-> 5

To give context to Mantanco's answer, the direct answer to your question is to use a class method. This is a method invoked with the class:

#app/models/user.rb
class User < ActiveRecord::Base
   def completed user
      user.todo_items.where(completed: true).count
   end
end

This is called using:

@user = User.find params[:id]
@user = User.completed user

What you need is an instance method -- a method which works on an instance of a class:

#app/models/user.rb
class User < ActiveRecord::Base
   def completed_items
      todo_items.where(completed: true).count
   end
end

This will allow you to call:

@user = User.find params[:id]
@user.completed_items

You'll be able to see the difference between class and instance methods here: http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/

Upvotes: -1

matanco
matanco

Reputation: 2129

so you wrote "accepts a user as a parameter" so you should do the following:

def self.get_completed_count(user)
  user.todo_items.where(completed: true).count
end

and you can call it:

User.get_completed_count(user)

but the above code doesn't make any sense because better is to do it as instance method:

def get_completed_count
  self.todo_items.where(completed: true).count
end

this code will return the same results just on instance.

you can call it:

User.find(id).get_completed_count

i assume that TodoItem has completed as a boolean(better create a scope and use this scope inside the method instead of where(completed: true)).

Upvotes: 7

Related Questions