简体   繁体   中英

ActionController::ParameterMissing with Delete Action

I am fairly new to Rails and working on building my first app outside of courses like CodeAcademy. I am running into issues with Parameters + building a delete function. I can display all tasks on an index when I make the private tasks_params record look like this:

    private 
    def task_params 
        params.require(:task).permit(:name, :description, :due_date)
    end

Clicking on the delete function and confirming it throws this:

param is missing or the value is empty: task

When I no longer "require" the :task param and instead "permit" it, like so:

private 
def task_params 
    params.permit(:task, :name, :description, :due_date)
end

My app returns:

Couldn't find Task with 'id'=

Below are the routes.rb file, Tasks_Controller.rb file, and index.html.erb files. Any help will be much appreciated.

routes.rb

 get 'signup' => 'users#new'
  resources :users
  get 'login' => 'sessions#new'
  post 'login' => 'sessions#create'
  delete 'logout' => 'sessions#destroy'
  get 'tasks' => 'tasks#index'
  get 'tasks/new' => 'tasks#new'
  post 'tasks' => 'tasks#create'
  delete 'tasks/:id' => 'tasks#delete'
  get 'tasks/:id/edit' => 'tasks#edit' 
  put 'tasks/:id' => 'tasks#update'
end

Task_Controller.rb class TasksController < ApplicationController def index @task = Task.last(100) end

def new
    @task = Task.new
end 

def create
    @task = Task.new(task_params) 
    if @task.save
        redirect_to '/tasks' 
    else 
        render 'new' 
    end 
end

def edit
    @task = Task.find(task_params[:id])
end

def update
    @task = Task.find(task_params[:id])
    @task.update_attributes(task_params[:description])

    redirect_to '/tasks'

end

def delete
    @task = Task.find(task_params[:id])
    @task.delete

    redirect_to tasks_path
end

private 
def task_params 
    params.permit(:task, :name, :description, :due_date)
end

end

index.html.erb

<h2>Your Tasks</h2>
<div class="tasks">
    <div class="container">
        <% @task.each do |task| %> 
            <div class="task"> 
                <p>Title: <%= task.name %></p> 
                <p>Description: <%= task.description %></p>
                <p>Due Date: <%= task.due_date %></p>
                <%= link_to 'delete', task_path(task), 
                         method: :delete, 
                         data: { confirm: 'Are you sure?' } %>  
            </div>
        <% end %>
    </div>
</div>

Thanks in advance!

It's nice that you're trying to write your controllers from scratch, but I think Rails is all about convention over configuration, and you should embrace that.

This means that a good starting point for your controllers is checking how the scaffolded controllers look, since they follow Rails convention (I don't know if you knew that, but you can have rails generate the controller code automatically for you by using rails g scaffold_controller NameOfYourModel ).

If you look at the generated code (it will be very easy for you to understand given how for you've gotten), you'll see that we don't use strong parameters for the :destroy action (you're naming it wrong, per convention it should be def destroy instead of def delete ).

Inside that action, you'll simply find the model with @task = Task.find(params[:id]) , so you don't use task_params there.

task_params 's goal is to ensure you have a safe, sanitized params before using it for mass assignment (like in Task.create(task_params) ), but in the destroy action we don't need that, we just need to find the record and destroy it.

Some extra tips:

  • Open http://localhost:3000/rails/info/routes , it will help you a lot in the long run. It will give you the routes your routes.rb is generating, and it's named helper, which you can use to create links, and also tell you what params the link helpers expect and what params your controller will recieve when using that route.

  • Read the Rails routing guide . It's very valuable. For the code you posted above, you have a very standard CRUD (create, read, update, destroy), so the rails scaffold is perfect to get you started. In your routes file, instead of manually declaring each route, you'll just declare resource :tasks , and it will create all the reoutes for you (index, show, create, update, destroy).

Rails is huge, and it will take a long time to master, but trust me, I've been coding on it for the last 6 years and it's awesome, worth every minute invested on it, and it compounds over time :)

Rory, Shouldn't your Delete action be like this?

def destroy
  @article = Task.find(params[:id])
  @article.destroy

  redirect_to tasks_path
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM