This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/completing-a-todo
Where is it setting “completed_at”?
I’m confused on this too. Did you figure out where that came from?
class CompletionsController < ApplicationController
def create
current_user.todos.find(params[:todo_id]).touch :completed_at
redirect_to todos_path
end
end
completed_at
is set by the touch method:
Saves the record with the updated_at/on attributes set to the current time. Please note that no validation is performed and only the after_touch, after_commit and after_rollback callbacks are executed.
If attribute names are passed, they are updated along with updated_at/on attributes.
I’m still a bit green with Rails and the idea of multiple controllers handling concerns for a model, e.g. CompletionsController setting completed_at
for todos, is pretty foreign to me. Is this a common pattern? What is the benefit of this setup versus creating a complete
method in TodosController?
From what I’ve learned it is better to try and not create methods in controllers outside the default ones.
This makes our API follow the REST conventions (wiki) which makes the API cleaner (I guess this could have personal preference).
Hope that helps!
It is a very common pattern, and recommended by a lot of very experienced practitioners - if not everyone. While there might be some cases where you want to do things differently, you will want to stick to this pattern as much as you can.
Try to keep your controllers public interface to the 7 Rails restful actions. You will have a cleaner, more approachable, more standard code base when it comes to controllers, and you can use rails routing helpers resource and resources out of box.
I was doing this tutorial, and had ran the migration successfully, however when I ran the spec it says: -
Failure/Error: todo = Todo.new(completed_at: Time.current) ActiveRecord::StatementInvalid: Could not find table 'todos'
Any idea why is this happening? If it’s the case where my test database does not have the table Todo, any idea why rake db:migrate
which seem to have ran successfully on my development database but not on my test database?
You might have to run rake db:test:prepare
to ensure the test DB matches development. Newer versions of Rails aim to do this automatically, but it’s not always reliable.
Is anyone having problems getting the User completes todo successfully to pass after implementing the CompletionsController?
class CompletionsController < ApplicationController
def create
current_user.todos.find(params[:todo_id]).touch :completed_at
redirect_to todos_path
end
end
Still getting the following error
Failures:
1) User completes todo successfully
Failure/Error: expect(page).to have_css(".todo li.completed", text: "Buy milk")
expected to find css ".todo li.completed" with text "Buy milk" but there were no matches
# ./spec/features/user_completes_todo_spec.rb:13:in `block (2 levels) in <top (required)>'
It looks like the database is being updated correctly
Processing by CompletionsController#create as HTML
Parameters: {"authenticity_token"=>"4NnIeG5+9nDuSoRqaNDc1ygq7nh4WWoX5vWNlPW7CsQzPqKuQUxVSSoZ6qrWhgyWVM3Ge7yCq56fkxWTX5UsDw==", "todo_id"=>"3"}
Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."email" = ? AND "todos"."id" = ? LIMIT 1 [["email", "a@emai.com"], ["id", 3]]
(0.2ms) begin transaction
SQL (0.8ms) UPDATE "todos" SET "updated_at" = '2016-08-31 12:43:49.631686', "completed_at" = '2016-08-31 12:43:49.631686' WHERE "todos"."id" = ? [["id", 3]]
(50.2ms) commit transaction
Redirected to http://localhost:3000/todos
Any suggestions?
SOLVED. All down to a silly spelling mistake