Używam klejnotu devise do procedur sign_in / sign_out.
Wygenerowałem pliki widoków z devise, używając rails g devise views
Zauważyłem, że istnieje plik devise / session / new.html.erb, który zawiera formularz do logowania.
Stworzyłem inny plik devise / session / _form.html.erb i zrobiłem to <%= render 'form' %>
w pliku new.html.erb i to wyszło bardzo dobrze.
Teraz chciałem dołączyć ten formularz z innego kontrolera. Tak więc w kontrolerze o nazwie „main” (konkretnie na stronie widoku) „main / index.html.erb” umieściłem <%= render 'devise/sessions/form' %>
plik. Wygląda na to, że włączenie działało dobrze, ale pojawia się następujący błąd.
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:
Wygląda na to, że część form_for (zasób, ...) jest przyczyną problemu (co działa dobrze, jeśli jestem na oryginalnej stronie devise sign_in ... Jak mogę rozwiązać ten problem w sposób railsowy?
Osobiście wolę używać funkcji „render”, aby dołączyć formularz, zamiast pisać wbudowane kody HTML.
Czy muszę określić coś (zasób) w „głównym” kontrolerze?
Będę wdzięczny za twoją pomoc. Dziękuję Ci.
źródło
Odpowiedzi:
Jak mówi Andres, formularz wywołuje pomocników, które są określone przez Devise i dlatego nie są obecne, gdy uzyskujesz dostęp do formularza Devise z kontrolera innego niż Devise.
Aby obejść ten problem, musisz dodać następujące metody do klasy pomocniczej kontrolera, pod którym chcesz wyświetlać formularz. Alternatywnie możesz po prostu dodać je do pomocnika aplikacji, aby były dostępne w dowolnym miejscu.
def resource_name :user end def resource @resource ||= User.new end def devise_mapping @devise_mapping ||= Devise.mappings[:user] end
Źródło: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/
źródło
inherited_resources
.helper_method :resource_name, :resource_class, :resource, :devise_mapping
(:resource_class
wydaje się, że jest to wymagane w nowszych wersjach Devise).Spróbuj tego też ... sprawdź to pytanie .
Źródło
<%= 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 %>
źródło
Utworzony formularz działa, gdy jest renderowany z kontrolera Devise, ponieważ „zasób” jest definiowany za pomocą Devise. Przyjrzyj się implementacji Devise SessionsController - z tego, co rozumiem, próbujesz odtworzyć „nową” akcję. Metoda „build_resource” jest prawdopodobnie tym, czego szukasz.
Warden gem gdzie obiekty „resource” pochodzą. Jeśli chcesz zagłębić się głębiej, dobrze byłoby tam zajrzeć.
źródło
Aby doprecyzować zaakceptowaną odpowiedź, używamy tego pomocnika, aby zezwolić na różne rodzaje zasobów:
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
gdzie
admin_controller?
jest coś, co mamy wcześniej wApplicationController
obsłudze przekierowań logowania:def admin_controller? !devise_controller? and request.path =~ /^\/admin/ end helper_method :admin_controller?
źródło
Otrzymałem ten sam błąd,
undefined local variable or method "resource"
który opisałeś z jednego z moich kontrolerów, ponieważ w mojej klasie bazowej kontrolera brakowało następującego (błąd Rails-API ActionController :: API był uszkodzony):include ActionController::Helpers
Dlatego w widoku nie można było rozwiązać metod pomocniczych z Devise.
Aby Devise działało z Rails-API, musiałem dołączyć:
class ApplicationController < ActionController::API include AbstractController::Rendering include AbstractController::Layouts include ActionController::MimeResponds include AbstractController::Translation include ActionController::ImplicitRender include ActionController::Helpers
źródło