Reputation: 297
I'm new to rails and I am building a todo list app. I am trying to set it up- like Trello so I can output multiple lists and have items under each list. So currently I can create lists, and within each list create list items. Everything is working by taking the player between the different pages but I am trying to combine it all into one page.
Here is a mock up image of what I am trying to get to with each list:
I mostly have it working. I can create new lists and they automatically appear on the page. If I add items the items appear underneath each list. Here is an image of what I have so far:
The last piece I am having an issue with is including the ability to create list items right there in the index page from within each list. If you look at the mock up image above there is a text field on the top of the list. I am looking to do the same thing and create a new item for that list.
I am getting this error "NoMethodError in TodoLists#index". I understand why it is erroring out since the index action doesn't know about todo_items but can't figure out how to make it work.
Here is my page index page where I want everything to happen from:
<div class="row wrapper border-bottom white-bg page-heading">
<div class="col-lg-10">
<h2>Todo Lists</h2>
<ol class="breadcrumb">
<li>
<a href="index.html">Home</a>
</li>
<li>
<a>Todo Lists</a>
</li>
<li class="active">
<strong>Lists</strong>
</li>
</ol>
</div>
<div class="col-lg-2"></div>
</div>
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-md-4">
<div id="nestable-menu">
<%= link_to "Create New List", new_todo_list_path, :class => "btn btn-white btn-sm" %>
</div>
</div>
</div>
<div class="row">
<% @todo_lists.each do |todo_list| %>
<div class="col-lg-4">
<div class="ibox">
<div class="ibox-content">
<h3><%= link_to todo_list.title, todo_list %>
-
<span class="small"><%= todo_list.description %></span>
</h3>
<p class="small">
<i class="fa fa-hand-o-up"></i>
Drag task between list</p>
<div class="input-group">
<%= form_for([@todo_list, @todo_list.todo_items.build]) do |f| %>
<%= f.text_field :content, placeholder: "New Todo" %>
<%= f.submit %>
<% end %>
</div>
<ul class="sortable-list connectList agile-list" id="todo">
<%= todo_list.todo_items.each do |todo_items| %>
<li class="warning-element" id="task1">
<%= todo_items.content %>
<div class="agile-detail">
<%= link_to "Delete", todo_list_todo_item_path(todo_list, todo_items.id), :class=>"pull-right btn btn-xs btn-danger", method: :delete, data: { confirm: "Are you sure?" } %>
<i class="fa fa-clock-o"></i>
<%= todo_items.created_at.strftime('%m/%d/%Y %I:%M %p') %>
</div>
</li>
<% end %>
</ul>
</div>
</div>
</div>
<% end %>
</div>
</div>
todo_lists_controller:
class TodoListsController < ApplicationController
before_action :set_todo_list, only: [:show, :edit, :update, :destroy]
# GET /todo_lists
# GET /todo_lists.json
def index
@todo_lists = TodoList.all
end
# GET /todo_lists/1
# GET /todo_lists/1.json
def show
end
# GET /todo_lists/new
def new
@todo_list = TodoList.new
end
# GET /todo_lists/1/edit
def edit
end
# POST /todo_lists
# POST /todo_lists.json
def create
@todo_list = TodoList.new(todo_list_params)
respond_to do |format|
if @todo_list.save
format.html { redirect_to @todo_list, notice: 'Todo list was successfully created.' }
format.json { render :show, status: :created, location: @todo_list }
else
format.html { render :new }
format.json { render json: @todo_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todo_lists/1
# PATCH/PUT /todo_lists/1.json
def update
respond_to do |format|
if @todo_list.update(todo_list_params)
format.html { redirect_to @todo_list, notice: 'Todo list was successfully updated.' }
format.json { render :show, status: :ok, location: @todo_list }
else
format.html { render :edit }
format.json { render json: @todo_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todo_lists/1
# DELETE /todo_lists/1.json
def destroy
@todo_list.destroy
respond_to do |format|
format.html { redirect_to root_url, notice: 'Todo list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo_list
@todo_list = TodoList.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_list_params
params.require(:todo_list).permit(:title, :description)
end
end
todo_items_controller:
class TodoItemsController < ApplicationController
before_action :set_todo_list
before_action :set_todo_item, except: [:create]
def create
@todo_item = @todo_list.todo_items.create(todo_item_params)
redirect_to @todo_list
end
def destroy
if @todo_item.destroy
flash[:success] = "Todo List item was deleted."
else
flash[:error] = "Todo List item could not be deleted."
end
redirect_to @todo_list
end
def complete
@todo_item.update_attribute(:completed_at, Time.now)
redirect_to @todo_list, notice: "Todo item completed"
end
private
def set_todo_list
@todo_list = TodoList.find(params[:todo_list_id])
end
def set_todo_item
@todo_item = @todo_list.todo_items.find(params[:id])
end
def todo_item_params
params[:todo_item].permit(:content)
end
end
Routes:
resources :todo_lists do
resources :todo_items do
member do
patch :complete
end
end
end
Any help is appreciated!
Upvotes: 0
Views: 66
Reputation: 297
I ended up getting it working! All I had to do in the end was change:
<%= form_for([@todo_list, @todo_list.todo_items.build]) do |f| %>
to
<%= form_for([todo_list, TodoItem.new],:remote => true) do |f| %>
Upvotes: 1