На первый взгляд система достижений кажется простой, но может быстро стать довольно сложной.
Во-первых, вы должны определить, какие достижения вы хотите предоставить. Вы можете присуждать:
- Значки
- Очки
- Звания
Конечно, вы также захотите сделать различные комбинации из них.
Неочевидные, но часто задаваемые вопросы:
- способность знать, как продвигается к определенному ранг или значок .
- возможность скрывать некоторые значки
В мире RoR я нашел 3 сторонние библиотеки в свободном доступе. Как часто, нет волшебной пули, и вы должны выбрать одну в соответствии с вашими потребностями.
Badgeable
Badgeable - это простой DSL, который реализует только систему badge . Это динамично и просто для понимания. Этот пример взят из официальной документации:
badge "Fancy Pants" do
thing Meal
subject :person
count
Meal.where(:price_cents.gte => 10000).count >= 12
end
conditions do |meal|
meal.restaurant.city != meal.eater.city
end
end
Это наградило бы значок Fancy Pants посетителю, который съел 12 дорогих блюд, где награда была вне города. Он включает в себя интересные функции, такие как невидимый значок, но не может награждать один и тот же значок несколько раз. По умолчанию, Badgeable добавляет хуки после создания наблюдаемой записи. В приведенном выше примере условие значка выполняется после каждого создания Meal .
Он поддерживает ActiveRecord и Mongoid.
Пути Славы
Пути Славы сильно отличается от Badgeable . Этот камень больше подходит к Очкам и Рангов . Он отделяет логику для вычисления значков (наблюдателя) от логики для описания значков (класс достижений). Возможно, для вас будет более естественным, если вы уже используете шаблон Observer . Обратите внимание, что это чистый Ruby, в Paths of Glory нет DSL.
В классе достижений вы описываете свои уровни, на что рассчитываете и как присваиваете достижения:
level 1, :quota => 2
level 2, :quota => 4
level 3, :quota => 6
set_thing_to_check { |user| user.posts.count }
def self.award_achievements_for(user)
return unless user
return if user.has_achievement?(self)
user.award_achievement(self)
end
Часть наблюдателя очень классическая:
observe :post
def after_save(post)
Teacher.award_achievements_for(post.user) unless post.new_record?
end
Это плохо документировано, но вы можете найти пример приложения, используя его здесь .
Включает помощников для отслеживания прогресса до следующего ранга . Поскольку он использует классические функции рельсов, он должен быть совместим со всеми доступными рельсами ORM.
Merit
Заслуга , кажется, является более полным сокровищем по этому вопросу, банкомат. Это позволяет определять значки , точки и правила с DSL.
Для значков это выглядит так:
grant_on ['users#create', 'users#update'], :badge => 'autobiographer', :temporary => true do |user|
user.name.present? && user.address.present?
end
Будет проверяться как создание, так и обновление, если пользователь указал свой адрес. Значок будет удален, если пользователь удалит его адрес.
Для очков он способен подсчитать балл на основе нескольких моделей:
score 20, :on => [ 'comments#create', 'photos#create' ]
Для рангов это очень похоже на значки. Разница в основном в уровне :
set_rank :stars, :level => 2, :to => Commiter.active do |commiter|
commiter.branches > 1 && commiter.followers >= 10
end
set_rank :stars, :level => 3, :to => Commiter.active do |commiter|
commiter.branches > 2 && commiter.followers >= 20
end
Этот драгоценный камень также предоставляет средства для вычисления значков или рангов в заданиях cron, а не после каждой записи в объекты:
task :cron => :environment do
MeritRankRules.new.check_rank_rules
end
Под капотом Мерит использует Амбри для хранения значков информации. Это должно помочь уменьшить шум в хранилище данных и сделать его немного быстрее.
Для MongoMapper доступна экспериментальная поддержка. Я не нашел никаких средств, чтобы иметь невидимые значки или следить за продвижением к значку.