I wanted to create a todo application with rails and I decided to add a log in function. I added the users table and two migrations: one to add the column "user_id" to the todo table and one to make "user_id" not null. This means that in order to create a todo, it has to have a user ID. Create column:
class AddColumnOnCreateTodos < ActiveRecord::Migration[6.1]
def change
add_column(:todos, :user_id, :integer)
end
end
change to not null:
class ChangeColumnOnCreateTodos < ActiveRecord::Migration[6.1]
def change
change_column_null(:todos, :user_id, false)
end
end
Now, everything works just fine. I can access the current logged in user and the column got added with the not null constraint. However, somehow the create function in my todo_controller does not work. Every time I want to create a new todo, the SQL statement is the following:
INSERT INTO "todos" ("title", "description", "created_at", "updated_at") VALUES (?, ?, ?, ?)
The create method of my todo_controller looks like this:
def create
@todo = Todo.new(todo_params)
if @todo.save
redirect_to to_dos_path
else
render :new
end
end
And the todo_params like this:
private
def todo_params
user = Current.user.id
puts user
params.require(:todo).permit(:title, :description, user)
end
It somehow does not know that the user_id column was added. I'm new to rails, so what am I missing? I did reset the entire database, did a rollback, migration, rake db:reset db:migrate, etc. I don't know why it doesn't work.
You have added a not null constraint, but you are creating the Todo without the user foreign key, that's why its not saving.
You need to create the Todo through association, but you need to have this association first in your user model:
has_many :todos
This will allow you to create a todo through association
user = Current.user.id
todo = user.todos.create(todo_params)
Another note about the permit method in todo_params, permit is used to allow the parameters coming with your request to be used in creating or updating records, only the attributes inside the permit function will be used to create your todo. So adding user
in permit won't really change anything since this value doesn't initially exist within the request parameters.
Another solution is to merge the permitted params with the user_id, so it can be used in creating the todo
def todo_params
user = Current.user.id
params.require(:todo).permit(:title, :description).merge(user_id: user.id)
end