2010-11-02 22 views
117

我正在为sign_in/sign_out程序使用设计gem。在不同的控制器中设计窗体

我生成的视图文件从色器件,使用rails g devise views

我看到有其中载有sign_in形式有一项/会话/ 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(资源,...)部分引起的问题(如果我原来的色器件sign_in页...我该如何解决在轨方式这个问题呢?

上工作正常

我个人更喜欢使用“渲染”功能,包括形式,而不是内联编写HTML代码。

我必须注明“主”控制器内的东西(资源)?

我会感谢您的帮助,谢谢

+0

有没有解决方法...?截至11月16日我还没有真正得到使用渲染的解决方案..虽然如果我只是键入内联代码,它看起来工作得很好.. – user482594 2010-11-16 15:13:18

+0

你找到了解决方案吗? – neebz 2011-06-29 13:15:45

+0

是的,我选择了解决我的问题的答案。这比我想象的更简单。 – user482594 2011-10-17 18:04:01

回答

221

由于安德烈斯说,调用的形式,其被设计指定的,所以当你从非设计控制器访问设计形式不存在帮手。

要解决这个问题,你需要将以下方法添加到辅助类要显示在表格的控制器。或者,您可以将它们添加到您的应用程序助手中,以使它们在任何地方都可用。

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/

+8

在阅读完本文后,我终于明白了一切。 – user482594 2011-09-19 03:08:22

+5

优秀。确保它在助手中,而不是在控制器中。另外,如果您有其他资源(例如,也可以登录的公司)并且您想要加载其表单,这可能会导致严重问题。确保重新定义名称,并且路由也可能成为问题。 – 2013-03-28 13:55:41

+1

这个解决方案的坏处是它打破了'inherited_resources'。 – jrhorn424 2013-10-02 22:04:54

4

您创建的表单在从Devise控制器呈现时工作,因为“资源”是通过Devise定义的。看看Devise SessionsController的实现 - 根据我的理解,您试图复制“新”操作。 “build_resource”方法可能是你正在寻找的。

Warden宝石是这里的“资源”对象的来源。如果你想深入挖掘,那就应该看看。

+0

我只是在mains_controller中调用'build_resource',但它调用了[未定义的局部变量或方法'build_resource']错误。我尝试在'mains_controller'的顶部插入'include Devise :: Controllers :: InternalHelpers'来包含devise内部帮助器,但它也会通过'AbstractController :: ActionNotFound'调用错误 – user482594 2010-11-03 05:45:12

8

可以试试这个也...检查这个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 %> 
+0

这不是所有答案的最佳做法吗? – allegutta 2014-04-30 17:56:52

2

我得到了同样的错误undefined local variable or method "resource"你从我的控制器的一个形容,因为我的控制器基类是缺少以下(Rails的API的ActionController :: API有过错):

include ActionController::Helpers 

因此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

精益求精接受的答案,我们用这个帮手,让不同类型的资源:

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? 
相关问题