Подтвердить что ты не робот

Современные инструменты для Ruby/Rails для построения системы достижений

Мне интересно создать надежную систему достижений для моего приложения Ruby on Rails.

Достижения могут происходить множеством способов. Обычно у нас бы есть некоторые критерии, которые могут случиться с несколькими моделями, некоторые из которых необходимы, некоторые необязательные (сочетание и совпадение), которые запускают достижение.

Я бы сказал, что это похоже на систему достижений здесь или на значки Foursquare. В идеале, если есть современный инструмент, который может помочь абстрагировать большую часть работы в некоторых DSL, это было бы фантастически.

Мне интересно узнать, как другие решили эту проблему, используя Ruby или Ruby on Rails. Построение этого с нуля кажется необоснованным, поскольку я уверен, что он был разрешен много раз.

4b9b3361

Ответ 1

Система достижений кажется простой на первый взгляд, но может быстро стать довольно сложной.

Во-первых, вы должны определить, какие достижения вы хотите предоставить. Вы можете наградить:

  • Значки
  • Точки
  • Ряды

Конечно, вы также захотите сделать различные комбинации. Неочевидные, но часто задаваемые функции:

  • способность знать свой прогресс в отношении определенного ранга или значка.
  • способность скрыть некоторые значки

В мире RoR я обнаружил, что 3 независимых библиотеки доступны. Как часто, нет волшебной пули, и вам нужно выбрать ее в соответствии с вашими потребностями.

Badgeable

Badgeable - это простой DSL, который реализует только систему значков. Это динамично и легко понять. Этот пример приведен из официальной документации:

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

Он наградил значком "Необычные брюки" закусочной, который съел 12 дорогих блюд, где награждение еды было за городом. Он включает в себя интересные функции, такие как невидимый значок, но не может присуждать одинаковые кратные значки. По умолчанию Badgeable добавляет крючки после создания наблюдаемой записи. В приведенном выше примере состояние значка выполняется после каждого создания Meal.

Он поддерживает как ActiveRecord, так и Mongoid.

Пути славы

Paths of Glory отличается от Badgeable. Этот камень больше связан с очками и званиями. Он отделяет логику от вычисления значков (наблюдателя) от логики для описания значков (класс Achivement). Возможно, для вас было бы более естественно, если вы уже используете шаблон Observer. Обратите внимание, что это чистый Ruby, там нет DSL в Paths of Glory.

В классе Achievement вы описываете свои уровни, то, что вы считаете и как награждать достижения:

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

Merit кажется более полным камнем об этом предмете, ATM. Это позволяет определять значки, баллы и правила с помощью 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

Под капотом Merit используется Ambry для хранения информации о значках. Это должно помочь уменьшить шум на вашем хранилище данных и сделать его немного быстрее. Там есть экспериментальная поддержка для MongoMapper. Я не нашел никаких средств, чтобы иметь невидимые значки или следить за прогрессом в отношении значка.

Ответ 2

activerecord-reputation-system для пользователей Twitter, если вам нужно комплексное решение.

Ответ 3

Вы посмотрели Badgeable?