user1480797
user1480797

Reputation: 185

How to create custom method in Rails?

I'm currently trying to use a custom method in Rails and I do not know how to do so. Apart from the default methods in the controller, I wanted to add the following:

  def cancel
    @newsletter = Newsletter.find(params[:id])

   respond_to do |format|

  #SendGrid Newsletter API - Delete Newsletter Schedule
  SendGrid.delete_schedule(@newsletter.name)

  @newsletter.status = "CANCELLED"

  @newsletter.save

  format.html { redirect_to newsletters_url }
  format.json { head :no_content }
end

end

The method is just like the default :destroy method but it doesn't actually destroys the object.

In my view, I had the following:

<% @newsletters.each do |newsletter| %>
  <tr>
    <td><%= newsletter.identity %></td>
    <td><%= newsletter.name %></td>
    <td><%= newsletter.recipients %></td>
    <td><%= newsletter.subject %></td>
    <td><%= newsletter.html %></td>
    <td><%= newsletter.text %></td>
    <td><%= newsletter.schedule %></td>
    <td><%= newsletter.status %></td>
    <td><%= link_to 'Show', newsletter %></td>
    <td><%= link_to 'Edit', edit_newsletter_path(newsletter) %></td>
    <td><%= link_to 'Destroy', newsletter, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    <td><% if newsletter.status == "SCHEDULED" %><%= link_to 'Cancel', newsletter, method: :cancel, data: { confirm: 'Cancel Schedule?' }%><% end %></td>

  </tr>
<% end %>

I got the error: No route matches [POST] "_newsletter url__"

When I rake routes, there isn't any route for the error above. May I know how to add the route and why is the route needed?


UPDATE Currently, I still have the no route matches error. Below are all my files related to the 'Cancel' method:

routes.rb

  resources :newsletters do
    match '/cancel/:id' => 'newsletters#cancel', :as => :cancel
  end

newsletters_controller.rb

def cancel @newsletter = Newsletter.find(params[:id])

respond_to do |format|

#SendGrid Newsletter API - Delete Newsletter Schedule
  SendGrid.delete_schedule(@newsletter.name)

  @newsletter.status = "CANCELLED"

  @newsletter.save

  format.html { redirect_to newsletters_path(@newsletter) }
  format.json { head :no_content }
end
end

newsletters/index.html.erb

<%= link_to 'Cancel', newsletter_cancel_path(newsletter) %>

Upvotes: 2

Views: 2687

Answers (3)

edralph
edralph

Reputation: 1831

I think you're mistaking the method: argument in the link_to as corresponding to the method in the controller. Actually it is referring to the RESTful HTTP verb i.e. :post, :delete and :put. So you don't pass the controller action through this way.

Instead you can pass in :controller and :action arguments...

Better still create a route in routes.rb and use the path that rails generates.

match "/cancel/:id", to: "controller#cancel", as: :cancel

and then the link_to would be something like:

link_to 'Cancel', cancel_path(newsletter)

Update: The error you're getting is with the redirect_to in your cancel method (in the controller). Change the newsletters_url to newsletter_path(@newsletter) instead.

If you want to redirect back to the show page for a single newsletter, then you need to do the above (where you pass in the @newsletter parameter), if you want it to go back to the newsletters index page then it'll be newsletters_path.

You can check the existence of the routes by typing rake routes in your terminal. You'll see all the route names there.

Do you still get an error after changing to redirect_to newsletter_path(@newsletter)?

The thing that doesn't quite strike true is that you're getting a no POST route defined - which usually points to a malformed form_for. Examine your newsletter related forms especially any where you don't do the regular form_for @newsletter do |f|.

Upvotes: 1

aNoble
aNoble

Reputation: 7072

You should have a line like this in your config/routes.rb file

resources :newsletters

You'll want to change it to this

resources :newsletters do
  member do
    put 'cancel'
  end
end

You'll want to take a look at the routing guide that Иван Бишевац posted. You'll also want to understand basic restful routing and how Rails handles GET, POST, PUT, DELETE, etc.

Upvotes: 2

Иван Бишевац
Иван Бишевац

Reputation: 14631

Here is complete explanation about routing: http://guides.rubyonrails.org/routing.html

Upvotes: 1

Related Questions