取消订阅方法抛出未定义的方法update_attributes错误

时间:2014-11-20 21:42:04

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

所以,我有一个我从头开始构建的新闻通讯应用程序,我试图实现取消订阅功能。

但是,当用户单击取消订阅时,日志显示NilClass的未定义方法update_attributes错误。

我做错了什么?

subscribers_controller.rb

class SubscribersController < ApplicationController    
  def new
    @subscriber = Subscriber.new
  end

  def create
    @subscriber = Subscriber.new(subscriber_params)

    if @subscriber.save
      redirect_to root_path
    else
      render :new
    end
  end

  def unsubscribe
    subscriber = Subscriber.find_by_unsubscribe_hash(params[:unsubscribe_hash])
    if subscriber.update_attributes(:subscription, false)
      redirect_to root_path
    else
      flash[:notice] = "Error while un-subscribing, please try again"
    end
  end

  private

  def subscriber_params
    params.require(:subscriber).permit(:email, :category_id, :created_at, :updated_at, :category => {},
                                      category_attributes: [:id, :name, :category_type, :created_at, :updated_at])
  end

   def permitted_params
    params.permit(:email, :category_id, :created_at, :updated_at, :category => {},
                                      category_attributes: [:id, :name, :category_type, :created_at, :updated_at])
  end

  def attr_params_category
    params.require(:account).permit(category_attributes: [:id, :name, :category_type, :created_at, :updated_at, :category => {}])
  end

end

subscriber.rb

class Subscriber < ActiveRecord::Base
  before_create :add_unsubscribe_hash

  belongs_to :category  
  has_many :quote_histories

  validates :email, presence: true
  validates :category_id, presence: true

  def choose_quote(cat)
    quote = cat.quotes.uniq_quote_for(self.id).order("RANDOM()").first 
    return nil if quote.nil? # so if we didn't able to find in quote lets return from here with nil!k
    return quote if self.quote_histories.create quote ande(quote_id: quote.id) # so here we won't need to test for nil! 
    #so this will reduce the time to perform this operation
  end

  private

  def add_unsubscribe_hash
    self.unsubscribe_hash = SecureRandom.hex
  end
end

schema.rb

  create_table "subscribers", force: true do |t|
    t.string   "email"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "category_id"
    t.string   "unsubscribe_hash"
  end

的routes.rb

  get 'subscribers/unsubscribe/:unsubscribe_hash' => 'subscribers#unsubscribe', :as => 'unsubscribe'

然后在邮件视图模板中

  <span><%= link_to 'un-subscribe', unsubscribe_url(@subscriber.unsubscribe_hash) %></span>

调试日志

2014-11-20T22:17:15.937062+00:00 heroku[router]: at=info method=GET path="/subscribers/unsubscribe/cbdb9b40962f1cc6b475096b73c6d5fd" host=motiv8.io request_id=981ed2f0-390e-4d33-888f-26aa8c8060ff fwd="99.234.25.253" dyno=web.1 connect=5ms service=11ms status=500 bytes=1754
2014-11-20T22:17:15.927014+00:00 app[web.1]: Started GET "/subscribers/unsubscribe/cbdb9b40962f1cc6b475096b73c6d5fd" for 99.234.25.253 at 2014-11-20 22:17:15 +0000
2014-11-20T22:17:15.932546+00:00 app[web.1]: 
2014-11-20T22:17:15.932548+00:00 app[web.1]: RuntimeError ("cbdb9b40962f1cc6b475096b73c6d5fd"):
2014-11-20T22:17:15.932550+00:00 app[web.1]:   app/controllers/subscribers_controller.rb:32:in `unsubscribe'
2014-11-20T22:17:15.932552+00:00 app[web.1]: 
2014-11-20T22:17:15.932553+00:00 app[web.1]: 
2014-11-20T22:17:15.930282+00:00 app[web.1]: Processing by SubscribersController#unsubscribe as HTML
2014-11-20T22:17:15.930302+00:00 app[web.1]:   Parameters: {"unsubscribe_hash"=>"cbdb9b40962f1cc6b475096b73c6d5fd"}
2014-11-20T22:17:15.931362+00:00 app[web.1]: Completed 500 Internal Server Error in 1ms

和rails c:

Subscriber.find_by_unsubscribe_hash("cbdb9b40962f1cc6b475096b73c6d5fd")
  Subscriber Load (2.2ms)  SELECT  "subscribers".* FROM "subscribers"  WHERE "subscribers"."unsubscribe_hash" = 'cbdb9b40962f1cc6b475096b73c6d5fd' LIMIT 1
  Subscriber Load (2.2ms)  SELECT  "subscribers".* FROM "subscribers"  WHERE "subscribers"."unsubscribe_hash" = 'cbdb9b40962f1cc6b475096b73c6d5fd' LIMIT 1
 => nil 

1 个答案:

答案 0 :(得分:1)

查看您的取消订阅操作。

替换

if subscriber.update_attributes(:subscription, false)

if subscriber.update_attribute(:subscription, false)

这里#update_attributes可以像{subscription:false}那样使用哈希,但是你传递了两个不同的参数。所以类似的解决方案是:

if subscriber.update_attributes({subscription: false})

无论如何,我更新了整个取消订阅动作的代码块。

 def unsubscribe
   subscriber = Subscriber.find_by_unsubscribe_hash(params[:unsubscribe_hash])
   if subscriber and subscriber.update_attribute(:subscription, false)
     redirect_to root_path
   elsif subscriber.nil?
     flash[:notice] = "Subscription not found"
   else
     flash[:notice] = "Error while un-subscribing, please try again"
  end
end