Rails activemodel 和 actionmailer 联系我表格 returns 没有路由匹配 [POST]
Rails activemodel & actionmailer contact me form returns no route matches [POST]
我正在尝试使用 activemodel 创建一个 'contact me' 表单以避免生成不必要的表格。当我提交联系表格时,rails returns 错误 No route matches [POST] "/contact/new"
,尽管有以下路线
config/routes.rb
resources :contact, only: [:new, :create]
rake routes
returns 以下...
contact_index POST /contact(.:format) contact#create
new_contact GET /contact/new(.:format) contact#new
controller/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
mailers/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
models/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
views/contact/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 %>
您正在将表单提交给 new_contact_path
(/contact/new
),其方法是 GET
而不是 POST
。默认情况下,form_for
构造一个 method
设置为 post
的表单。
因此,当您提交时,rails 正在寻找 new_contact_path
和 POST
不存在的动词,因此没有路由匹配。
从 form_for
中删除 url
选项。
<%= form_for @contact do |f| %>
# form elements
<% end %>
Rails 将负责 url 提交,表单将提交至 contacts_path
(/contacts
)
要使上述代码正常工作,您的路由定义应如下所示:
resources :contacts, only: [:new, :create]
声明资源时应使用复数形式:
resources :contacts, only: [:new, :create]
这符合 RESTful 您正在对资源集合进行操作的想法。
您的表格应该 post 到 contacts_path
而不是 new_contacts_path
。 new
和 edit
操作响应 GET 并仅在 rails.
中呈现表单
事实上,您可以将记录传递给 form_for
并使用约定优于配置:
<%= form_for(@contact) %>
# ...
<% end %>
这将自动路由到 contacts_path
。您很少需要为 rails.
中的表单手动设置 URL
我正在尝试使用 activemodel 创建一个 'contact me' 表单以避免生成不必要的表格。当我提交联系表格时,rails returns 错误 No route matches [POST] "/contact/new"
,尽管有以下路线
config/routes.rb
resources :contact, only: [:new, :create]
rake routes
returns 以下...
contact_index POST /contact(.:format) contact#create
new_contact GET /contact/new(.:format) contact#new
controller/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
mailers/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
models/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
views/contact/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 %>
您正在将表单提交给 new_contact_path
(/contact/new
),其方法是 GET
而不是 POST
。默认情况下,form_for
构造一个 method
设置为 post
的表单。
因此,当您提交时,rails 正在寻找 new_contact_path
和 POST
不存在的动词,因此没有路由匹配。
从 form_for
中删除 url
选项。
<%= form_for @contact do |f| %>
# form elements
<% end %>
Rails 将负责 url 提交,表单将提交至 contacts_path
(/contacts
)
要使上述代码正常工作,您的路由定义应如下所示:
resources :contacts, only: [:new, :create]
声明资源时应使用复数形式:
resources :contacts, only: [:new, :create]
这符合 RESTful 您正在对资源集合进行操作的想法。
您的表格应该 post 到 contacts_path
而不是 new_contacts_path
。 new
和 edit
操作响应 GET 并仅在 rails.
事实上,您可以将记录传递给 form_for
并使用约定优于配置:
<%= form_for(@contact) %>
# ...
<% end %>
这将自动路由到 contacts_path
。您很少需要为 rails.