2010-11-02 2 views
117

Я использую драгоценный камень для процедур sign_in/sign_out.Форма разработки в другом контроллере

я сгенерировал просмотр файлов из завещанию, используя rails g devise views

я увидел там был DEViSE/сессии/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 (ресурс, ...) часть вызывает проблему (которая работает нормально, если я на оригинальном DEViSE sign_in страницы ... Как я могу решить эту проблему в рельсах пути?

Я лично предпочитаю использовать «визуализации» функции, чтобы включить форму, а не писать HTML-коды рядный.

должен ли я указать кое-что (ресурса) в рамках «основного» контроллера?

Я буду оцените вашу помощь.

+0

Есть ли какое-нибудь решение ...? По состоянию на ноябрь/16 я не получил решение с помощью рендеринга. Хотя, если я просто набираю встроенный код, он отлично работает, кажется .. – user482594

+0

Вы нашли решение для этого? – neebz

+0

Да, я выбрал ответ, который решает мою проблему. Это было проще, чем я думал. – user482594

ответ

221

Как говорит Андрес, форма вызывает помощников, которые заданы 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/

+8

. Я, наконец, все понимаю сегодня после прочтения этого. – user482594

+5

Отлично. Удостоверьтесь, что он идет в помощнике, а не в контроллере. Кроме того, это может привести к огромным проблемам, если у вас есть другие ресурсы (например, компании, которые также могут войти в систему), и вы хотите загрузить их форму. Не забудьте переопределить имена, и маршрутизация также может стать проблемой. –

+1

Плохая вещь об этом решении заключается в том, что он разбивает 'inherited_resources'. – jrhorn424

4

Форма, которую вы создали, работает при визуализации с помощью контроллера Devise, потому что «resource» определяется с помощью Devise. Взгляните на реализацию Devise SessionsController - из того, что я понимаю, вы пытаетесь воспроизвести «новое» действие. Метод «build_resource» - это, вероятно, то, за чем вы заботитесь.

Драгоценный камень Warden. Если вы хотите копать глубже, это будет место для просмотра.

+0

Я только что назвал 'build_resource' с mains_controller, но он вызывает ошибку [undefined local variable or method 'build_resource]. Я попытался включить в себя встроенный помощник, добавив «включить Devise :: Controllers :: InternalHelpers» в начало «mains_controller», но также вызывает ошибку с помощью «AbstractController :: ActionNotFound» – user482594

8

Может попробовать это также ... проверить это question.

Source

<%= 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 %> 
+0

Разве это не лучшая практика всех ответов? – allegutta

2

я получаю ту же ошибку undefined local variable or method "resource" вы описываете от одного из моих контроллеров, потому что мой контроллер базового класса пропускал следующее (Rails-API ActionController :: API был виноват):

include ActionController::Helpers 

Таким образом, вспомогательные методы из 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 
2

Для уточнения о принятом ответа, мы используем этот помощник, чтобы различные типы ресурсов:

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?