#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
, потому что вы инициализируете переменную там. Во всех других местах, где вы хотите использовать форму, вам придется сделать то же самое.