Разработать форму в другом контроллере
Я использую собственный камень для процедур sign_in/sign_out.
Я сгенерировал файлы представлений из проекта, используя rails g devise views
Я видел, что был файл dev//new.html.erb, содержащий форму для sign_in.
Я создал другой файл dev/session/_form.html.erb и сделал <%= render 'form' %>
в файле new.html.erb, и это получилось очень хорошо.
Теперь я хотел включить эту форму из другого контроллера. Поэтому в контроллере под названием "main" (в частности, на странице просмотра) "mains/index.html.erb" я включил файл <%= render 'devise/sessions/form' %>
. Кажется, что включение работает нормально, но я получаю следующую ошибку.
NameError in Mains#index
Showing /home/administrator/Ruby/site_v4_ruby/app/views/devise/sessions/_form.html.erb where line #1 raised:
undefined local variable or method `resource' for #<#<Class:0x007f1aa042d530>:0x007f1aa042b870>
Extracted source (around line #1):
1: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
2: <p><%= f.label :email %><br />
3: <%= f.text_field :email %></p>
4:
Кажется, что часть form_for (resource,...) вызывает проблему (которая отлично работает, если я нахожусь на исходной странице sign_in dev... Как я могу решить эту проблему в режиме rails?
Я лично предпочитаю использовать функцию "render" для включения формы, вместо того, чтобы писать html-коды inline.
Должен ли я указывать что-то (ресурс) в "главном" контроллере?
Буду признателен за вашу помощь. Спасибо.
Ответы
Ответ 1
Как говорит Андрес, форма вызывает помощников, которые заданы Devise, и поэтому нет, когда вы обращаетесь к форме Devise с контроллера не-Devise.
Чтобы обойти это, вам нужно добавить следующие методы в вспомогательный класс контроллера, который вы хотите отобразить в форме. Кроме того, вы можете просто добавить их в помощник приложения, чтобы сделать их доступными где угодно.
def resource_name
:user
end
def resource
@resource ||= User.new
end
def devise_mapping
@devise_mapping ||= Devise.mappings[:user]
end
Источник: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/
Ответ 2
Можно попробовать это также... проверьте этот вопрос.
Источник
<%= form_for("user", :url => user_session_path) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
<%= f.submit 'Sign in' %>
<%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>
Ответ 3
Форма, которую вы создали, работает при визуализации с помощью контроллера Devise, потому что "resource" определяется с помощью Devise. Взгляните на реализацию Devise SessionsController - из того, что я понимаю, вы пытаетесь воспроизвести "новое" действие. Метод "build_resource" - это, вероятно, то, что вам нужно.
Warden gem - это объект, из которого происходят объекты ресурса. Если вы хотите углубиться в глубь, это будет место для поиска.
Ответ 4
Я получал ту же ошибку undefined local variable or method "resource"
, которую вы описываете с одного из моих контроллеров, потому что в моем базовом классе контроллера отсутствовало следующее (Rails-API ActionController:: API был виноват):
include ActionController::Helpers
Таким образом, вспомогательные методы из Devise не могли быть разрешены в представлении.
Чтобы заставить Devise работать с Rails-API, мне нужно было включить:
class ApplicationController < ActionController::API
include AbstractController::Rendering
include AbstractController::Layouts
include ActionController::MimeResponds
include AbstractController::Translation
include ActionController::ImplicitRender
include ActionController::Helpers
Ответ 5
Чтобы уточнить принятый ответ, мы используем этот помощник, чтобы разрешать различные типы ресурсов:
def resource_name
@resource_name ||= if admin_controller?
:admin_user
else
:user
end
end
def resource
@resource ||= resource_name.to_s.classify.constantize.new
end
def devise_mapping
@devise_mapping ||= Devise.mappings[resource_name]
end
где admin_controller?
- это то, что мы имеем раньше, в ApplicationController
для обработки переадресаций для входа:
def admin_controller?
!devise_controller? and request.path =~ /^\/admin/
end
helper_method :admin_controller?