在 rails 中保存记录时出现 couter_cache 错误
Getting couter_cache error when saving record in rails
我在 rails 应用程序中尝试对项目进行投票时遇到错误。好像跟计数器缓存有关
错误
#<ArgumentError: wrong number of arguments (given 3, expected 1..2)>
error.backtrace
["/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/callbacks.rb:451:in `increment!'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/draper-4.0.1/lib/draper/automatic_delegation.rb:12:in `method_missing'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/associations/belongs_to_association.rb:91:in `update_counters'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/associations/belongs_to_association.rb:54:in `increment_counters'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:169:in `block in _create_record'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:192:in `block in each_counter_cached_associations'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:191:in
app/models/vote.rb
# == Schema Information
#
# Table name: votes
#
# id :bigint not null, primary key
# stance :integer default("Unsure")
# votable_type :string
# created_at :datetime not null
# updated_at :datetime not null
# user_id :integer
# votable_id :integer
#
# Indexes
#
# index_votes_on_user_id (user_id)
# index_votes_on_votable_id_and_votable_type (votable_id,votable_type)
#
class Vote < ApplicationRecord
attr_accessor :get_verified
enum stance: { 'Unsure' => 0, 'Yes' => 1, 'No' => 2 }
belongs_to :user, counter_cache: true
validates :user_id, uniqueness: { scope: %i[votable_type votable_id] }
belongs_to :votable, polymorphic: true
validates :votable, presence: true
scope :verified, -> { where('user_id in ( select user_id from verifications )') }
scope :yays, -> { where(stance: true) }
scope :nays, -> { where(stance: false) }
scope :undecided, -> { where(stance: nil) }
end
app/controllers/votes_controller.rb
class WeVote::VotesController < WeVoteController
load_and_authorize_resource
def create
@vote.user = current_user_or_guest
@vote.save!
if @vote.get_verified == 'true'
redirect_to new_verification_path
else
redirect_to request.referer
end
rescue ArgumentError => e
byebug
Rails.logger.error(e)
redirect_to request.referer, notice: { alert: e }
end
def destroy
@vote.destroy
redirect_to request.referer
end
private
def vote_params
params.require(:vote).permit(:votable_type, :votable_id, :stance, :get_verified)
end
end
问题的关键在于回溯的第二行,您可以在其中看到 draper
gem 正在拦截未知消息。
那个特定的方法正在寻找特定的调用,如果它不需要对它拦截的消息采取行动,它会尝试将它们引导回主应用程序。
不幸的是,它这样做的方式与您的 Ruby 版本不兼容,我怀疑它是第 3 版。Ruby 对方法参数的内部处理在不同版本之间发生了变化2.x 和 3.x,Draper 的发布版本依赖于 2.x 实现。
This issue in the Draper repo 与您在代码库中看到的相匹配。
在发布正式修复程序之前,您可以更新 Gemfile 以直接指向 Draper 存储库而不是剪切 gem 版本:
gem 'draper', github: 'drapergem/draper'
我在 rails 应用程序中尝试对项目进行投票时遇到错误。好像跟计数器缓存有关
错误
#<ArgumentError: wrong number of arguments (given 3, expected 1..2)>
error.backtrace
["/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/callbacks.rb:451:in `increment!'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/draper-4.0.1/lib/draper/automatic_delegation.rb:12:in `method_missing'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/associations/belongs_to_association.rb:91:in `update_counters'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/associations/belongs_to_association.rb:54:in `increment_counters'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:169:in `block in _create_record'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:192:in `block in each_counter_cached_associations'",
"/Users/antarr/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/counter_cache.rb:191:in
app/models/vote.rb
# == Schema Information
#
# Table name: votes
#
# id :bigint not null, primary key
# stance :integer default("Unsure")
# votable_type :string
# created_at :datetime not null
# updated_at :datetime not null
# user_id :integer
# votable_id :integer
#
# Indexes
#
# index_votes_on_user_id (user_id)
# index_votes_on_votable_id_and_votable_type (votable_id,votable_type)
#
class Vote < ApplicationRecord
attr_accessor :get_verified
enum stance: { 'Unsure' => 0, 'Yes' => 1, 'No' => 2 }
belongs_to :user, counter_cache: true
validates :user_id, uniqueness: { scope: %i[votable_type votable_id] }
belongs_to :votable, polymorphic: true
validates :votable, presence: true
scope :verified, -> { where('user_id in ( select user_id from verifications )') }
scope :yays, -> { where(stance: true) }
scope :nays, -> { where(stance: false) }
scope :undecided, -> { where(stance: nil) }
end
app/controllers/votes_controller.rb
class WeVote::VotesController < WeVoteController
load_and_authorize_resource
def create
@vote.user = current_user_or_guest
@vote.save!
if @vote.get_verified == 'true'
redirect_to new_verification_path
else
redirect_to request.referer
end
rescue ArgumentError => e
byebug
Rails.logger.error(e)
redirect_to request.referer, notice: { alert: e }
end
def destroy
@vote.destroy
redirect_to request.referer
end
private
def vote_params
params.require(:vote).permit(:votable_type, :votable_id, :stance, :get_verified)
end
end
问题的关键在于回溯的第二行,您可以在其中看到 draper
gem 正在拦截未知消息。
那个特定的方法正在寻找特定的调用,如果它不需要对它拦截的消息采取行动,它会尝试将它们引导回主应用程序。
不幸的是,它这样做的方式与您的 Ruby 版本不兼容,我怀疑它是第 3 版。Ruby 对方法参数的内部处理在不同版本之间发生了变化2.x 和 3.x,Draper 的发布版本依赖于 2.x 实现。
This issue in the Draper repo 与您在代码库中看到的相匹配。
在发布正式修复程序之前,您可以更新 Gemfile 以直接指向 Draper 存储库而不是剪切 gem 版本:
gem 'draper', github: 'drapergem/draper'