Rails activemodel& actionmailer联系我表单返回没有路由匹配[POST]

时间:2017-01-22 05:36:08

标签: ruby-on-rails forms actionmailer activemodel

我正在尝试使用activemodel创建一个“与我联系”表单,以避免生成不必要的表。当我提交联系表单时,rails会返回错误No route matches [POST] "/contact/new",尽管有以下路由

配置/ routes.rb中

resources :contact, only: [:new, :create]

rake routes返回以下内容......

   contact_index POST   /contact(.:format)                     contact#create
   new_contact GET    /contact/new(.:format)                 contact#new

控制器/ contact_controller.rb

class ContactController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(params[:contact])
    if @contact.valid?
      ContactMailer.contact_submit(@contact).deliver
      flash[:notice] = "Thank you for your email, I'll respond shortly"
      redirect_to new_contact_path
    else
      render :new
    end
  end
end

寄件人/ contact_mailer.rb

class ContactMailer < ActionMailer::Base
  default to: ENV[EMAIL_ADDRESS]

  def contact_submit(msg)
    @msg = msg
    mail(from: @msg.email, name: @msg.name, message: @msg.message)
  end
end

模型/ contact.rb

class Contact
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :message

  validates_format_of :email, :with => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
  validates_presence_of :message
  validates_presence_of :name

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end
end

的观点/接触/ new.html.erb

<%= form_for @contact, url: new_contact_path do |f| %>
  <div class="form-inputs">
    <div class="form-group">
      <%= f.label :name %><br>
      <%= f.text_field :name %>
    </div>
    <div class="form-group">
      <%= f.label :email %><br>
      <%= f.email_field :email %>
    </div>
    <div class="form-group">
      <%= f.label :message %><br>
      <%= f.text_area :message %>
    </div>
  </div>
  <div class="form-actions">
    <%= f.submit %>
  </div>
<% end %>

2 个答案:

答案 0 :(得分:1)

您将表单提交至new_contact_path/contact/new),其方法为GET而不是POST。默认情况下,form_for会将method设置为post的表单构建。

因此,当您提交时,rails正在寻找new_contact_path POST动词,而该动词不存在,因此没有路由匹配。

url删除form_for选项。

<%= form_for @contact do |f| %>
  # form elements
<% end %>

Rails会处理要提交的网址,表单会提交给contacts_path/contacts

要使上述代码生效,您的路径定义应如下所示:

resources :contacts, only: [:new, :create]

答案 1 :(得分:1)

在声明资源时,您应该使用复数形式:

resources :contacts, only: [:new, :create]

这与RESTful的想法相关,即您正在对一组资源进行操作。

您的表单应发布到contacts_path而不是new_contacts_pathnewedit操作会响应GET,只是在rails中呈现表单。

实际上,您只需将记录传递给form_for并使用约定优于配置:

<%= form_for(@contact) %>
  # ...
<% end %>

这会自动转到contacts_path。您很少需要在rails中手动设置表单的URL。