Ruby-on-rails 在不同的控制器中设计表单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4081744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:32:11  来源:igfitidea点击:

Devise form within a different controller

ruby-on-railsruby-on-rails-3devise

提问by user482594

I am using a devise gem for sign_in/sign_out procedures.

我正在为 sign_in/sign_out 程序使用设计 gem。

I generated views files from devise, using rails g devise views

我从设计生成视图文件,使用 rails g devise views

I saw there was a devise/sessions/new.html.erb file which contained a form for sign_in.

我看到有一个包含 sign_in 表单的 devise/sessions/new.html.erb 文件。

I created another file devise/sessions/_form.html.erb and did <%= render 'form' %>within a new.html.erb file, and that worked out very fine.

我创建了另一个文件 devise/sessions/_form.html.erb 并<%= render 'form' %>在 new.html.erb 文件中进行了操作,结果非常好。

Now, I wanted to include this form from the different controller. So in a controller called 'main', (specifically, within view page) 'mains/index.html.erb' I included <%= render 'devise/sessions/form' %>file. It seems that inclusion worked fine, but I am getting the following error.

现在,我想从不同的控制器中包含这个表单。所以在一个名为“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: 

It seems that form_for(resource,...) part is causing the problem (which works fine if I am on the original devise sign_in page... How can I resolve this problem in rails way?

似乎 form_for(resource,...) 部分导致了问题(如果我在原始设计 sign_in 页面上工作正常......我如何以 rails 方式解决这个问题?

I personally prefer to use 'render' function to include the form, rather than writing html codes inline.

我个人更喜欢使用“渲染”函数来包含表单,而不是内联编写 html 代码。

Do I have to specify something (resource) within the 'main' controller?

我是否必须在“主”控制器中指定某些内容(资源)?

I will appreciate your help. Thank you.

我会感谢你的帮助。谢谢你。

回答by Rupert Madden-Abbott

As Andres says, the form calls helpers which are specified by Devise and so aren't present when you access a Devise form from a non-Devise controller.

正如安德烈斯所说,表单调用由 Devise 指定的帮助程序,因此当您从非设计控制器访问设计表单时不存在。

To get around this, you need to add the following methods to the helper class of the controller you wish to display the form under. Alternatively, you can just add them to your application helper to make them available anywhere.

为了解决这个问题,您需要将以下方法添加到您希望在其下显示表单的控制器的帮助程序类中。或者,您可以将它们添加到您的应用程序助手中,以便在任何地方使用它们。

  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

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

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

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

回答by jsp

Can try this also...check this 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 %> 

回答by Andres Freyria

The form you created works when rendered from a Devise controller because "resource" is defined through Devise. Take a look at the implementation of the Devise SessionsController- from what I understand, you're attempting to replicate the "new" action. The method "build_resource" is probably what you're looking after.

您创建的表单在从设计控制器呈现时有效,因为“资源”是通过设计定义的。看看Devise SessionsController的实现——据我所知,你试图复制“新”动作。方法“build_resource”可能就是您所关注的。

The Wardengem is where the "resource" objects are coming from. If you wish to dig deeper, that'd be the place to look.

监狱长的宝石是这里的“资源”对象的来源。如果您想深入挖掘,那将是您寻找的地方。

回答by bbozo

To refine on the accepted answer, we use this helper to allow different types of resources:

为了改进已接受的答案,我们使用此助手来允许不同类型的资源:

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

where admin_controller?is something we have from before in the ApplicationControllerto handle login redirects:

这里admin_controller?是我们从之前的必须ApplicationController处理登录重定向:

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

回答by Christopher Oezbek

I was getting the same error undefined local variable or method "resource"you describe from one of my controllers, because my controller base class was missing the following (Rails-API ActionController::API was at fault):

undefined local variable or method "resource"从我的一个控制器中收到了与您描述的相同的错误,因为我的控制器基类缺少以下内容(Rails-API ActionController::API出错):

include ActionController::Helpers

Thus the helper methods from Devise could not be resolved in the view.

因此,无法在视图中解析来自 Devise 的辅助方法。

To make Devise work with Rails-API I needed to include:

为了使设计与 Rails-API 一起工作,我需要包括:

class ApplicationController < ActionController::API

  include AbstractController::Rendering
  include AbstractController::Layouts
  include ActionController::MimeResponds
  include AbstractController::Translation
  include ActionController::ImplicitRender
  include ActionController::Helpers