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


128

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

私はdeviseからviewsファイルを生成しました rails g devise views

sign_inのフォームを含むdevise / sessions / new.html.erbファイルがあったことを確認しました。

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

今、私は別のコントローラからこのフォームを含めたかったです。したがって、「メイン」と呼ばれるコントローラー(具体的には、ビューページ内)に「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、...)部分が問題を引き起こしているようです(元のdevise sign_inページにいる場合は問題なく動作します...この問題をRailsで解決するにはどうすればよいですか?

個人的には、HTMLコードをインラインで記述するよりも、render関数を使用してフォームを含めることを好みます。

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

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


何か解決策はありますか...?11月/ 16のように私は実際にレンダリング使用して解決策を持っていない..私はちょうど、インラインコードで入力すると、それがうまく動作しますが、それは...そうです
user482594

これに対する解決策を見つけましたか?
11

はい、問題を解決する答えを選びました。思っていたよりシンプルでした。
user482594 2011年

回答:


240

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/


6
優れた。コントローラーではなくヘルパーに配置するようにしてください。また、他のリソース(たとえば、ログインも可能な企業)がいて、フォームをロードしたい場合、これは大きな問題につながる可能性があります。名前を再定義してください。ルーティングも問題になる可能性があります。
マイケルシュミッツ2013年

1
このソリューションの悪い点は、それが壊れることinherited_resourcesです。
jrhorn424 2013年

6
これらのメソッドのスコープを制限するには(そして、他のgemとの名前空間の競合を回避するためなど)、上記のメソッドをコントローラー自体に追加してみてくださいhelper_method :resource_name, :resource_class, :resource, :devise_mapping(これ:resource_classは、新しいバージョンのDeviseでは必須のようです)。
2014

1
工夫したモデルが少ない場合、どのような解決策がありますか?
yozzz 2014年

2つのDeviseモデルがあり、ホームページで両方にログインする必要があります。どのようにあなたの答えに似た何かをするのですか?
DR_

8

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

ソース

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

これはすべての回答のベストプラクティスではありませんか?
allegutta 2014

4

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

ウォーデンの「リソース」のオブジェクトがどこから来ている逸品です。もっと深く掘り下げたい場合は、ここが最適です。


mains_controllerで 'build_resource'を呼び出したところ、[undefined local variable or method `build_resource ']エラーが発生しました。'mains_controller'の上部に 'include Devise :: Controllers :: InternalHelpers'を挿入してdevise内部ヘルパーを含めてみましたが、 'AbstractController :: ActionNotFound'
user482594

3

受け入れられた回答を絞り込むために、このヘルパーを使用してさまざまなタイプのリソースを許可します。

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?

2

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.