【问题标题】:Using Devise in different controller: undefined method "resource="在不同的控制器中使用设计:未定义的方法“资源=”
【发布时间】:2017-04-05 04:21:37
【问题描述】:

我有 Devise 4.2.1 和 Rails 5.0.1。我正在尝试在registrations 以外的控制器中使用设计sign_in。有一堆方法没有定义,所以我不得不将它们添加为助手:

module ApplicationHelper
  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

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

  def build_resource(hash=nil)
    self.resource = resource_class.new_with_session(hash || {}, session)
    # ^the source of the error^
  end

  def resource_class
    devise_mapping.to
  end
end

但现在我收到以下错误:

NoMethodError in Static#show
undefined method 'resource=' for (class)

我的代码中没有写“resource=”,当然也没有在错误指向的那一行(上面标记)。 我的服务器从哪里得到该错误?


另外,我想我只是使用标准的登录代码:

<%
build_resource({})
set_minimum_password_length
yield resource if block_given?
respond_with self.resource
%>

<% form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>
  ...

【问题讨论】:

  • 您将sign_in 方法从其默认位置之外移动的原因是什么?
  • @LeonardoPrado 我正在尝试构建一个登录部分,我可以在我的应用程序的任何位置呈现。
  • Static#show 方法和 static/show.html.erb 中的内容是什么?
  • @JoeMorano 你可以使用任何你想要的部分,并把它放在你想要的任何地方,但仍然让它通过注册控制器。

标签: ruby-on-rails ruby devise ruby-on-rails-5


【解决方案1】:

我相信您的问题有 2 个答案:为什么会发生此错误,以及如何在所有控制器上使用 sign_in 部分:

创建sign_in 部分

首先sign_in方法属于sessions,不是registrations注意不要换错控制器了:)

而且您只是添加了一些超出您想要的代码的代码。要创建部分登录以在任何地方使用,只需使用其中的默认设计表单:

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %>

  <%= f.label :password %><br />
  <%= f.password_field :password, autocomplete: "off" %>

  <% if devise_mapping.rememberable? -%>
    <%= f.check_box :remember_me %>
    <%= f.label :remember_me %>
  <% end -%>

  <%= f.submit "Log in" %>
<% end %>

build_resource({}) 的那部分不需要,因为它会在您提交表单时由 Devise 自己处理。由于不需要build_resource,您只需要在 ApplicationHelper 上添加以下代码:

module ApplicationHelper
  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

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

这应该足以在任何控制器视图中拥有一个登录表单。如果您需要对登录流程进行更多控制,可以查看Devise Readme 上的配置控制器 部分,了解有关如何创建可自定义控制器的更多信息。

为什么您的代码会引发 NoMethodError 错误

您的代码会引发 NoMethodError,因为您尚未为 @resource 实例变量定义 setter。它应该是:

def resource=(value)
  @resource = value
end

attr_writer :resource

我推荐这个问题以获取有关该主题的更多信息: Why use Ruby's attr_accessor, attr_reader and attr_writer?

【讨论】:

  • 至于我。当我添加资源设置器时,应用程序无法识别。它将其视为正常的局部变量。对我有用的解决方案就是分配@resource = user
猜你喜欢
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 2012-06-30
相关资源
最近更新 更多