web-dev-qa-db-ja.com

別のコントローラー内でフォームを考案する

Sign_in/sign_outプロシージャにdevise gemを使用しています。

Rails g devise viewsを使用して、deviseからビューファイルを生成しました

Sign_inのフォームを含むdevise/sessions/new.html.erbファイルがあるのを見ました。

別のファイルdevise/sessions/_form.html.erbを作成し、new.html.erbファイル内で<%= render 'form' %>を実行しましたが、それは非常にうまくいきました。

今、私は別のコントローラーからこのフォームを含めたかった。したがって、「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ページにいる場合は正常に機能します... Rails wayでこの問題を解決するにはどうすればよいですか? ?

個人的には、HTMLコードをインラインで記述するよりも、フォームを含めるために「レンダリング」機能を使用することを好みます。

「メイン」コントローラー内で何か(リソース)を指定する必要がありますか?

よろしくお願いします。ありがとうございました。

123
user482594

Andresが言うように、フォームは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/

232

これも試すことができます...これを確認してください question

ソース

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

「リソース」はDeviseで定義されているため、作成したフォームはDeviseコントローラーからレンダリングされたときに機能します。 Devise SessionsController -の実装を見てください。私が理解していることから、あなたは「新しい」アクションを複製しようとしています。メソッド「build_resource」はおそらくあなたが探しているものです。

Warden gemは、「リソース」オブジェクトの取得元です。もっと深く掘り下げたいなら、そこが見どころでしょう。

4
Andres Freyria

受け入れられた答えを改良するために、このヘルパーを使用してさまざまなタイプのリソースを許可します。

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?
3
bbozo

同じエラーが発生していましたundefined local variable or method "resource"コントローラーの基本クラスに次のものがないため、コントローラーの1つから記述します(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
2