Множественные контактные формы — Rails 3

#ruby #ruby-on-rails-3 #forms #contact

#ruby #ruby-on-rails-3 #формы #Контакты

Вопрос:

Я относительный новичок во всем этом, поэтому извините, если это звучит безумно!

Я использовал это руководство: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 (rendered — views /supports/_form.html.erb)

Итак, я могу вызвать модель / контроллер с локального хоста: 3000 / support / new, но если я попытаюсь отобразить ту же форму в другом представлении из корневого каталога, например, app / view /contact.html.erb, я получу:

 undefined method `model_name' for NilClass:Class
  

Я думаю, это потому, что он вызывает модель поддержки из каталога supports.

Должен ли я создавать экземпляр в @support, чтобы его можно было вызвать? Если да, то каков наилучший способ сделать это? Я думаю, что я почти на месте. Я просто хочу, чтобы контактная форма была на нескольких страницах, а не только в support / new

Спасибо

Чарли

Ответ №1:

Да, вам нужно будет создать @support переменную в каждом действии, которое вы хотите отобразить в своей форме.

Другим вариантом было бы реорганизовать форму, чтобы принять параметр, таким образом, вы немного более гибки. Например, с вашей точки зрения:

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

Теперь вместо того, чтобы ссылаться на @support в вашем _form.html.erb , вы бы ссылались просто support , поскольку это local_assign .

Еще одним вариантом было бы провести дальнейший рефакторинг формы и побеспокоиться о создании фактического form тега за пределами partial.

Такие как:

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 опцией, вы получите локальную переменную в вашем partial с тем же именем, что и у partial. Вы сохраняете немного больше гибкости в пути вашей формы, но все еще можете отображать суть того, какой Support объект находится внутри формы, оставаясь при этом согласованным в вашем приложении.

Чтобы уточнить, вы могли бы использовать это где-нибудь еще, выполнив что-то вроде:

app/views/foos/_create_foo_support.html.erb

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

Комментарии:

1. Привет, спасибо за ответ, я попробовал первое решение, но оно по-прежнему выдает ту же ошибку?

2. Можете ли вы опубликовать свой код просмотра, изменили ли вы свои ссылки на suppport вместо @support . Пожалуйста, обратите внимание, что с первым вам все равно потребуется где-то определить @support переменную. В вашем случае, откуда вы пытаетесь отобразить форму поддержки?

3. <%= render :partial => "supports/form", :locals => {:support => @support} %> у меня есть это в / views / contacts.html.erb, и у меня есть это в файле формы / views / support /form.html.erb <%= form_for support, :url => { :action => "create" }, :html => { :method => :post } do |f| %>

4. Ты имел в виду /views/contacts/index.html.erb ? В этом случае вам нужно было бы @support быть определенным в вашем index действии. Вы также могли бы просто передать Support.new , если вы всегда собираетесь его создавать. Наконец, :action => "create" это не обязательно, если вы делаете form_for support . Rails узнает, что support это новый объект, и выберет для вас подходящий путь.

5. эй, извините, я имею в виду /views /pages/contact.html.erb Я определю @support в контроллере страницы и посмотрю, работает ли это

Ответ №2:

Вы должны передавать @support объект везде, где вы используете свою контактную форму. Это работает в SupportsController#new , потому что вы инициализируете переменную там. Во всех других местах, где вы хотите использовать форму, вам придется сделать то же самое.