JosephA91 JosephA91 - 3 months ago 6
Ruby Question

How to target a model and access records nested two levels deep in Ruby on Rails?

I am trying to create a todo list application in ruby on rails that has 3 models as nested resources.

For Example:


  • User:
    has_many :todo_lists

  • TodoList:
    has_many :todo_items
    &
    belongs_to :user

  • TodoItem:
    belongs_to :todo_list
    &
    scope :completed, -> { where.not(completed_at: nil) }



Running
@user.todo_lists
returns the user's todo lists.

Running
@todo_lists.todo_items
returns the todo list's todo items.

Running
@todo_lists.todo_items.completed
returns the todo list's completed todo items.

But

Running
@user.todo_lists.todo_items
returns error:
NoMethodError: undefined method 'todo_items'
.

Running
@user.todo_lists.todo_items.completed
also returns error:
NoMethodError: undefined method 'todo_items'
.

We have tried
@user.todo_lists.map(&:todo_items).flatten
which returns all the todo items for a user but we cannot add the
.completed
scope.

Am I on the right track?

Answer

Try using has_many :through association.

In your user model define association:

has_many :todo_items, through: :todo_lists

You should than be able to get todo_items without getting todo_lists first.

user.todo_items.completed

Using the map you were on the right track.

user.todo_lists.map { |todo_list| todo_list.todo_items.completed }.flatten
Comments