如何解决仅在生产中使用Merit授予徽章的问题
我正在将一个语言学习游戏应用程序与ruby集成在一起,并使用Merit授予徽章。
部署到Heroku时遇到奇怪的行为。尽管徽章的数量似乎保持一致,但徽章本身在刷新后似乎会随机更改为其他徽章。
可能会潜伏着一些错误,但最糟糕的错误并没有在开发中(在localhost上)发生,这使得该站点几乎无法从Heroku中使用。
值得注意的是,我正在使用Sweet Alert在授予徽章后触发通知模式。由于页面刷新,我选择使用控制器动作#show而不是#create,这似乎是Merit文档中非官方的默认设置。
无论如何,我什至会为这个想法而烦恼,因为我一直在尝试调试Merit文件,而且没有得到任何帮助。
以下是优点文件:
badge_rules.rb
module Merit
class BadgeRules
include Merit::BadgeRulesMethods
def initialize
# If it creates user,grant badge
# Should be "current_user" after registration for badge to be granted.
# Find badge by badge_id,badge_id takes presidence over badge
# grant_on 'users#create',badge_id: 7,badge: 'just-registered',to: :itself
# grant_on 'registrations#create',to: :itself possibly for devise
# If it has 10 comments,grant commenter-10 badge
# grant_on 'comments#create',badge: 'commenter',level: 10 do |comment|
# comment.user.comments.count == 10
# end
# If it has 5 Votes,grant relevant-commenter badge
# grant_on 'comments#Vote',badge: 'relevant-commenter',# to: :user do |comment|
#
# comment.Votes.count == 5
# end
# Changes his name by one wider than 4 chars (arbitrary ruby code case)
# grant_on 'registrations#update',badge: 'autobiographer',# temporary: true,model_name: 'User' do |user|
#
# user.name.length > 4
# end
# if the user has the first perfect play of a particular game,grant badge
# generals
grant_on 'pages#notify_badges',model_name: 'User',badge: 'signed_up',to: :action_user
grant_on 'contact#send_message',badge: 'first_contact',to: :action_user
# check application controller for additional rules
# generals
# stats
grant_on 'plays#create',badge: 'made_first_rank',to: :user do |play|
User.top_users.first == play.user
end
grant_on 'plays#create',badge: 'made_second_rank',to: :user do |play|
User.top_users.second == play.user
end
grant_on 'plays#create',badge: 'made_third_rank',to: :user do |play|
User.top_users.third == play.user
end
# stats
conversations_rules = [
{
badge: 'first_post',model_name: 'Post',rule: 'resource.user.posts.count == 1',grant_on: 'posts#show'
},{
badge: 'tenth_post',rule: 'resource.user.posts.count == 10',{
badge: 'hundredth_post',rule: 'resource.user.posts.count == 100',{
badge: 'first_comment',model_name: 'Comment',rule: 'resource.user.comments.count == 1',grant_on: 'comments#create'
},{
badge: 'tenth_comment',rule: 'resource.user.comments.count == 10',{
badge: 'hundredth_comment',rule: 'resource.user.comments.count == 100',{
badge: 'first_message',model_name: 'Message',rule: 'resource.user.messages.count == 1',grant_on: 'messages#create'
},{
badge: 'tenth_message',rule: 'resource.user.messages.count == 10',{
badge: 'hundredth_message',rule: 'resource.user.messages.count == 100',grant_on: 'messages#create'
}
]
conversations_rules.each do |rule_hash|
grant_on rule_hash[:grant_on],badge: rule_hash[:badge],to: :user,model_name: rule_hash[:model_name] do |resource|
eval(rule_hash[:rule])
end
end
Language.all.pluck(:language_code).each do |language_code|
path = Rails.root.join("app/assets/images/badges/games/perfect_plays/#{language_code}")
filenames = Dir.children(path).map { |e| e.split('.') }
filenames.each do |fname|
grant_on 'plays#create',badge: fname[1],to: :user do |play|
play.perfect? && play.game.slug == fname[0] && play.game.language.language_code == language_code
end
end
end
end
end
end
merit.rb
Merit.setup do |config|
config.checks_on_each_request = true
config.add_observer 'ReputationChangeObserver'
end
badge_id = 0
badges = []
Language.all.pluck(:language_code).each do |language_code|
games_path = Rails.root.join("app/assets/images/badges/games/perfect_plays/#{language_code}")
pp_filenames = Dir.children(games_path)
pp_filenames.delete('.DS_Store')
pp_filenames.map { |e| e.split('.') }.each do |fname|
badges << {
id: (badge_id = badge_id+1),name: fname[1],description: fname[1].gsub("_"," ").titleize,custom_fields: {
image_path: "badges/games/perfect_plays/#{language_code}/#{fname.join('.')}",game_slug: fname[0],language_code: language_code
}
}
end
end
conversations_path = Rails.root.join("app/assets/images/badges/conversations/")
conversations_filenames = Dir.children(conversations_path)
conversations_filenames.delete('.DS_Store')
conversations_filenames.map { |e| e.split('.') }.each do |fname|
badges << {
id: (badge_id = badge_id+1),name: fname[0],custom_fields: {
image_path: "badges/conversations/#{fname.join('.')}"
}
}
end
general_path = Rails.root.join("app/assets/images/badges/general/")
general_filenames = Dir.children(general_path)
general_filenames.delete('.DS_Store')
general_filenames.map { |e| e.split('.') }.each do |fname|
badges << {
id: (badge_id = badge_id+1),custom_fields: {
image_path: "badges/general/#{fname.join('.')}"
}
}
end
stats_path = Rails.root.join("app/assets/images/badges/stats/")
stats_filenames = Dir.children(stats_path)
stats_filenames.delete('.DS_Store')
stats_filenames.map { |e| e.split('.') }.each do |fname|
badges << {
id: (badge_id = badge_id+1),custom_fields: {
image_path: "badges/stats/#{fname.join('.')}"
}
}
end
badges.each do |attrs|
Merit::Badge.create! attrs
end
这是在我的pages_controller.rb
中 def notify_badges
@user = current_user
head :ok
end
创建它是为了防止刷新页面使Sweet Alert模式消失。
class ReputationChangeObserver
def update(changed_data)
# description = changed_data[:description]
# If user is your meritable model,you can query for it doing:
user = User.where(sash_id: changed_data[:sash_id]).first
badge = Merit::Badge.find(changed_data[:merit_object][:badge_id])
NotifyBadgeJob.set(wait: 3.seconds).perform_later(user.id,badge.id)
# When did it happened:
# datetime = changed_data[:granted_at]
end
end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。