user984621
user984621

Reputation: 48453

Rails 4 - routing actions for contact form

I have two actions in the controller:

  def report
    @user = User.find_by_slug(params[:slug])
  end
  def reportForm
    @user = User.find_by_slug(params[:slug])

    Thread.new do
      mail = ...
    end
    @message = 'Thanks!'
  end

and in routes:

# User report form
  get "/user/:slug/report", to: "users#report"
 # Catch report form and action
  post "/user/:slug/report", to: 'users#reportForm'

And the view:

<form method="POST" action="/user/<%= @user.slug %>/reportForm">
...

But the problem is, that when I send the form, the action reportForm is not called and instead of that is only refresh the current page with the form.

What's wrong here?

Thank you guys.

Upvotes: 1

Views: 152

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

Form Helpers

The first thing that's wrong is you're not using the form helpers that Rails provides - this is a problem because you'll end up with niggly little problems like the one you're receiving:

#config/routes.rb
resources :users do
   get  :report #-> domain.com/users/:id/report
   post :reportForm #-> domain.com/users/:id/reportForm
end

#view
<%= form_tag user_reportForm_path(@user) do %>
   ...
<% end %>

Routes

The second issue you have is to do with your routes

You've set the following routes:

get "/user/:slug/report", to: "users#report"
post "/user/:slug/report", to: 'users#reportForm'

This means you've got to send the request to domain.com/user/user_slug/report. Your form sends the URL to reportForm...

You should see my routes above for the solution to this problem

But more importantly, you should read up on nested resources:

#config/routes.rb
resources :users do
   match :report, action: "reportForm", via: [:get, :post] #-> domain.com/users/:id/report
end

Slug

Finally, you're trying to use params[:slug] in your controller

With the resourceful routes you should be using in Rails, you'll be passing params[:id] most of the time. This should not be an issue (what is contained in params[:id] can be anything).

I would highly recommend looking at a gem called friendly_id, which makes including slugs in your application a lot simpler:

#app/models/user.rb
Class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: [:slugged, :finders]
end

This will allow you to call:

#app/controllers/users_controller.rb
Class UsersController < ApplicationController
    def reportForm
       User.find params[:id] #-> will use either `id` or `slug`
    end
end

Upvotes: 1

Related Questions