Reputation: 4711
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
Reputation: 11
The below code worked for me.
def get_completed_count
self.todo_items.where(completed: true).count
end
Upvotes: 0
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
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
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
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