Farklı bir denetleyici içinde form oluşturun


129

Sign_in / sign_out prosedürleri için bir tasarım mücevher kullanıyorum.

Kullanarak, devise'dan görünüm dosyaları oluşturdum rails g devise views

Sign_in için bir form içeren bir devise / sessions / new.html.erb dosyası olduğunu gördüm.

Başka bir dosya devise / sessions / _form.html.erb oluşturdum ve <%= render 'form' %>bir new.html.erb dosyası içinde yaptım ve bu çok iyi sonuç verdi.

Şimdi, bu formu farklı denetleyiciden eklemek istedim. Yani 'main' adlı bir denetleyiciye, (özellikle görünüm sayfası içinde) 'mains / index.html.erb' <%= render 'devise/sessions/form' %>dosyasını ekledim . Görünüşe göre dahil etme iyi çalıştı, ancak aşağıdaki hatayı alıyorum.

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, ...) kısmı soruna neden oluyor gibi görünüyor (eğer orijinal oturum açma sayfasındaysam iyi çalışıyor ... Bu sorunu raylar şeklinde nasıl çözebilirim?

Ben şahsen html kodlarını satır içi yazmak yerine, formu dahil etmek için 'render' fonksiyonunu kullanmayı tercih ediyorum.

'Ana' denetleyicide bir şey (kaynak) belirtmem gerekiyor mu?

Yardımını takdir edeceğim. Teşekkür ederim.


Herhangi bir çözüm var mı? Kasım / 16 itibariyle render kullanarak çözüme gerçekten sahip değilim .. ancak satır içi kodu
yazarsam

bunun için bir çözüm buldunuz mu?
neebz

Evet, sorunumu çözen cevabı seçtim. Düşündüğümden daha basitti.
user482594

Yanıtlar:


241

Andres'in dediği gibi, form Devise tarafından belirtilen yardımcıları çağırır ve bu nedenle Devise dışı bir denetleyiciden bir Devise formuna eriştiğinizde mevcut değildir.

Bunu aşmak için aşağıdaki yöntemleri, altında formu görüntülemek istediğiniz denetleyicinin yardımcı sınıfına eklemeniz gerekir. Alternatif olarak, her yerde kullanılabilir hale getirmek için bunları uygulama yardımcınıza ekleyebilirsiniz.

  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end

Kaynak: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/


6
Mükemmel. Denetleyiciye değil, yardımcıya girdiğinden emin olun. Ayrıca, başka kaynaklarınız varsa (örneğin, oturum açabilen şirketler) ve formlarını yüklemek istiyorsanız, bu büyük sorunlara yol açabilir. İsimleri yeniden tanımladığınızdan emin olun ve yönlendirme de bir sorun haline gelebilir.
Michael Schmitz

1
Bu çözümle ilgili kötü olan şey, kırılmasıdır inherited_resources.
jrhorn424

6
Bu yöntemlerin kapsamını sınırlamak (ve örneğin, diğer değerli taşlarla ad alanı çakışmasını önlemek) için, yukarıdaki yöntemleri denetleyicinin kendisine eklemeyi deneyin helper_method :resource_name, :resource_class, :resource, :devise_mapping(bu :resource_class, daha yeni Devise sürümlerinde bir gereklilik gibi görünüyor).
35'te spume

1
Tasarlanmış birkaç modelimiz varsa ne çözüm olmalı?
yozzz

İki Devise modelim var ve her ikisi için de ana sayfada oturum açmam gerekiyor. Cevabınıza benzer bir şeyi nasıl yapacağınıza dair bir fikriniz var mı?
DR_

8

Bunu da deneyebilir ... bu soruyu kontrol edin .

Kaynak

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

Bu, tüm cevapların en iyi uygulaması değil mi?
allegutta

4

Oluşturduğunuz form, bir Devise denetleyicisinden işlendiğinde çalışır çünkü "kaynak" Devise aracılığıyla tanımlanır. Devise SessionsController uygulamasına bir göz atın - anladığım kadarıyla "yeni" eylemi kopyalamaya çalışıyorsunuz. "Build_resource" yöntemi muhtemelen sizin aradığınız şeydir.

Warden "kaynak" nesneler nereden geldiğini mücevher. Daha derine inmek isterseniz, bakmanız gereken yer burasıdır.


Bir mains_controller ile 'build_resource' aradım, ancak [undefined local variable veya method `build_resource '] hatası veriyor. 'Mains_controller'ın üst kısmına' include Devise :: Controllers :: InternalHelpers 'ekleyerek dahili yardımcıyı dahil etmeyi denedim, ancak aynı zamanda' AbstractController :: ActionNotFound '
user482594

3

Kabul edilen yanıtı hassaslaştırmak için, bu yardımcıyı farklı kaynak türlerine izin vermek için kullanıyoruz:

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

nerede admin_controller?biz önce gelen bir şey bu ApplicationControllersap giriş yönlendirmelere:

def admin_controller?
  !devise_controller? and request.path =~ /^\/admin/
end
helper_method :admin_controller?

2

undefined local variable or method "resource"Denetleyicilerimden birinde açıkladığınız hatayı alıyordum , çünkü denetleyici temel sınıfımda aşağıdakiler eksikti (Rails-API ActionController :: API hatalıydı):

include ActionController::Helpers

Bu nedenle, Devise'ın yardımcı yöntemleri görünümde çözülemedi.

Devise'ın Rails-API ile çalışmasını sağlamak için şunları eklemem gerekiyordu:

class ApplicationController < ActionController::API

  include AbstractController::Rendering
  include AbstractController::Layouts
  include ActionController::MimeResponds
  include AbstractController::Translation
  include ActionController::ImplicitRender
  include ActionController::Helpers
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.