使用Ruby on Rails在页脚中创建联系表单

时间:2016-03-01 09:22:59

标签: ruby-on-rails ruby

我正在尝试在页面的页脚中创建一个联系表单,以便它在我的应用程序视图中。

我的应用程序控制器如下所示:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :configure_permitted_parameters, if: :devise_controller?
  protected

  @contact = Contact.new(contact_params)
  if @contact.save
    name = params[:contact][:name]
    email = params[:contact][:email]
    body = params[:contact][:comments]
    ContactMailer.contact_email(name, email, body).deliver
    flash[:success] = 'Message sent.'
    redirect_to ""
  else
    flash[:success] = 'Error occured, message has not been sent.'
    redirect_to ""
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :stripe_card_token, :email, :password, :password_confirmation) }
  end

  private
    def contact_params
      params.require(:contact).permit(:name, :email, :comments)
    end

end

我目前使用的局部视图在我的应用程序视图中看起来像这样:

<%= form_for @contact do |f| %>
    <div class="form-group">
        <%= f.label :name %>
        <%= f.text_field :name, class: 'form-control' %>
    </div>
    <div class="form-group">
        <%= f.label :email %>
        <%= f.email_field :email, class: 'form-control' %>
    </div>
    <div class="form-group">
        <%= f.label :comments %>
        <%= f.text_area :comments, class: 'form-control' %>
    </div>
    <%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>

我确定它有问题,但我无法理解控制器和模型是如何协同工作的。

2 个答案:

答案 0 :(得分:0)

protectedprivate之间的所有代码都在类的上下文中运行,因此在应用程序加载文件时。它应该抛出异常undefined method or variable params for ApplicationController:Class

您需要按请求运行它,例如:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :configure_permitted_parameters, if: :devise_controller?
  before_filter :set_contact

  private

  def set_contact
    @contact = Contact.new
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :stripe_card_token, :email, :password, :password_confirmation) }
  end

end

before_filter是一种告诉控制器在每次请求之前应该做什么的方法。您只需要设置@contact实例变量来显示并绑定表单,但是应该提交以在ContactsController上创建操作:

class ContactsController < ApplicationController
  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_email(@contact.name, @contact.email, @contact.body).deliver
      flash[:success] = 'Message sent.'
      redirect_to :back
    else
      flash[:success] = 'Error occurred, message has not been sent.'
      redirect_to :back
    end
  end

  private

  def contact_params
    params.require(:contact).permit(:name, :email, :comments)
  end
end

需要注意的一点是,before_filter将在每个操作之前运行,无论响应类型如何(即使是重定向,当您不显示任何内容时)。显然这是一种浪费,这就是为什么做以下事情可能更好:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :configure_permitted_parameters, if: :devise_controller?
  helper_method :new_contact

  private

  def new_contact
    Contact.new
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :stripe_card_token, :email, :password, :password_confirmation) }
  end   
end

#form

<%= form_for new_contact do %>

这样,只有在需要时才会在内存中构建新的联系人。

答案 1 :(得分:0)

也许你应该为联系人创建一个新的控制器:

# /app/controllers/contacts_controller.rb
class ContactsController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_email(@contact.name, @contact.email, @contact.comments).deliver
      # Or you can send @contact object and find name, email etc. values in mailer
      # ContactMailer.contact_email(@contact).deliver
      flash[:success] = 'Message sent.'
      redirect_to ""
    else
      flash[:success] = 'Error occured, message has not been sent.'
      redirect_to ""
    end
  end

  private

  def contact_params
    params.require(:contact).permit(:name, :email, :comments)
  end
end

您的表单将进入app/views/contacts/new.html.erb。页脚链接如下:

<%= 'Contact Us', new_contact_path %>