Разработать форму в другом контроллере

Я использую собственный камень для процедур 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?