用户中的NoMethodError#unsubscribe

时间:2016-11-15 16:22:23

标签: ruby ruby-on-rails-4 rubygems

我正在努力实现对我的rails邮件程序的取消订阅链接。不幸的是,我的代码打破了这个:

  

用户中的NoMethodError#unsubscribe - nil的未定义方法`unsubscribe_hash':NilClass

指向 /app/views/users/unsubscribe.html.erb 第3行

<h4>Unsubscribe from Mysite Emails</h4>
<p>By unsubscribing, you will no longer receive email...</p>
<%= simple_form_for(@user, unsubscribe_path(id: @user.unsubscribe_hash)) do |f| %>
    <%= f.hidden_field(:subscription, value: false) %>
    <%= f.submit 'Unsubscribe' %>
    <%= link_to 'Cancel', root_url %>
<% end %>

我的user_controller如下所示

class UsersController < ApplicationController
  protect_from_forgery

  def new
    @user = User.new
  end

  def create
    @user = User.new(secure_params)
    if @user.save
      flash[:notice] = "Thanks! You have subscribed #{@user.email} for Jobs Alert."
    else
      flash[:notice] = 'Error Subscribing! Kindly check your email and try again.'
    end
    redirect_to root_path
  end

  def unsubscribe
    user = User.find_by_unsubscribe_hash(params[:unsubscribe_hash])
    @user = User.find_by_unsubscribe_hash(user)
  end

  def update
    @user = User.find(params[:id])
    if @user.update(secure_params)
      flash[:notice] = 'Subscription Cancelled'
      redirect_to root_url
    else
      flash[:alert] = 'There was a problem'
      render :unsubscribe
    end
  end

  private

  def secure_params
    params.require(:user).permit(:email, :subscription)
  end

end

Route.rb

  resources :users, only: [:new, :create]
  get 'users/:unsubscribe_hash/unsubscribe' => 'users#unsubscribe', as: :unsubscribe
  patch 'users/update'

user.rb

class User < ActiveRecord::Base

  before_create :add_unsubscribe_hash, :add_true_to_users_table

  validates :email, :uniqueness => true
  validates_presence_of :email
  validates_format_of :email, :with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i

  private

  def add_unsubscribe_hash
    self.unsubscribe_hash = SecureRandom.hex
  end

  def add_true_to_users_table
    self.subscription = true
  end

end

取消订阅电子邮件中的取消订阅链接

# app/views/job_notifier/send_post_email.html.erb
...
<%= link_to "Unsubscribe", unsubscribe_url(id: @unsubscribe) %>.

错误的示意图

enter image description here

似乎我错过了什么,我是否需要在users_controller中定义一些内容?我一生都没有能够解决NoMethodError,或者我不明白它的全部内容。

2 个答案:

答案 0 :(得分:1)

您收到该错误是因为@user(在UsersController#unsubscribe中设置)为nil。对于nil:NilClass`来说,这就是undefined method unsubscribe_hash'中的“for nil:NilClass”。

这种方法似乎不正确:

def unsubscribe
  user = User.find_by_unsubscribe_hash(params[:unsubscribe_hash])
  @user = User.find_by_unsubscribe_hash(user)
end

您正在按unsubscribe_hash查找用户并将其分配给user,然后再次按unsubscribe_hash查找用户,但将user作为值传递给{ {1}}。

我相信这样的事情更符合预期:

find_by_unsubscribe_hash

答案 1 :(得分:1)

每当您在格式化的ruby中看到任何错误消息时:

undefined method 'method_name' for nil:NilClass

你被告知你正试图在零物体上调用某物,所以你应该关注为什么那个物体为零。您还会在日志中告知错误发生的位置 - 在您的情况下,它指的是行,在您的表单声明中引用@user中的@user.unsubscribe_hash

所以@user为零,在这种情况下它是零,因为负责呈现表单的控制器不是设置@user

user = User.find_by_unsubscribe_hash(params[:unsubscribe_hash])
@user = User.find_by_unsubscribe_hash(user)

现在为什么你试图找到用户,然后将该用户传递到第二行以找到@user超出我的原因,但无论如何真正的问题是你没有匹配{{1}的用户}

所以这个问题与调用你的取消订阅动作的内容有关......你忽略了将它添加到你的问题中,所以我无法帮助你,但这是你的重点所在。