多个联系表单 - Rails 3

时间:2011-11-07 14:40:52

标签: ruby ruby-on-rails-3 forms contact

我是这一切的相对新手,很抱歉,如果这听起来很疯狂!

我使用过本教程:http://www.railsmine.net/2010/03/rails-3-action-mailer-example.html

我有一个很好的新联系表格。

控制器位于app / controllers / support_controller.rb

class SupportsController < ApplicationController
  def new
    # id is required to deal with form
    @support = Support.new(:id => 1)
   end

  def create
    @support = Support.new(params[:support])
    if @support.save
      redirect_to('/', :notice => "Support was successfully sent.")
    else
      flash[:alert] = "You must fill all fields."
      render 'new'
    end
  end
end

模型位于/app/models/support.rb

class Support
  include ActiveModel::Validations

  validates_presence_of :email, :sender_name, :support_type, :content
  # to deal with form, you must have an id attribute
  attr_accessor :id, :email, :sender_name, :support_type, :content

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

  def read_attribute_for_validation(key)
    @attributes[key]
  end

  def to_key
  end

  def save
    if self.valid?
      Notifier.support_notification(self).deliver!
      return true
    end
    return false
  end
end

然而,视图仅适用于views / supports / new.html.rb(呈现 - views / supports / _form.html.erb)

所以我可以从localhost:3000 / support / new调用模型/控制器但是如果我尝试在根目录中的另一个视图中呈现相同的表单,例如app / view / contact.html.erb我得到:

undefined method `model_name' for NilClass:Class

我认为这是因为它正在支持模型远离支持目录。

我是否必须在@support上创建一个实例才能调用它?如果是这样,最好的方法是什么?我想我快到了。我只想在多个页面上使用联系表单,而不仅仅是在suppport / new

由于

查理

2 个答案:

答案 0 :(得分:1)

您必须在使用联系表单的任何地方传递@support对象。它在SupportsController#new中工作,因为您在那里初始化变量。在您想要使用表单的所有其他地方,您必须这样做。

答案 1 :(得分:1)

是的,您需要在要渲染表单的每个操作中创建一个@support变量。

另一个选择是重构表单以获取参数,这样你就会更灵活一些。例如,从您的观点来看:

<%= render :partial => "supports/form", :locals => {:support => @support} %>

现在,您不是在@support中引用_form.html.erb,而是简单地引用support,因为它是local_assign。

另一种选择是进一步重构表单,并担心在部分之外创建实际的form标记。

如:

app/views/supports/new.html.erb

<%= form_for @support do |form| %>
  <%= render :partial => "suppports/form", :object => form %>
<% end %>

app/views/supports/_form.html.erb

<%= form.text_field :foo %>
<%= form.text_field :bar %>
...

在这种情况下,当您使用partial选项呈现object时,您将获得部分中与局部名称相同的局部变量。您可以在表单的路径中保持更多的灵活性,但仍然可以在表单内部呈现Support对象的内容,同时在应用程序中保持一致。

为了澄清,您可以通过执行以下操作在其他地方使用它:

app/views/foos/_create_foo_support.html.erb

<%= form_for @foo.support do |form| %>
   <%= render :partial => "supports/form", :object => form %>
<% end %>