Как реализовать систему успеха в RoR

Я столкнулся с той же проблемой, но решение, которое мне помогло, было:

HTML:

<header class="container-fluid">
    ...
</header>
<nav class="row">
    <div class="navbar navbar-inverse navbar-static-top">
        ...
    </div>
</nav>

JavaScript:

document.onscroll = function() {
    if( $(window).scrollTop() > $('header').height() ) {
        $('nav > div.navbar').removeClass('navbar-static-top').addClass('navbar-fixed-top');
    }
    else {
        $('nav > div.navbar').removeClass('navbar-fixed-top').addClass('navbar-static-top');
    }
};

Где header был тег баннера над моей навигационной панелью

40
задан Danubian Sailor 8 August 2014 в 12:51
поделиться

2 ответа

Я согласен с вашей идеей использовать модель Achievement .

Однако вам, вероятно, не следует реализовывать триггеры в своих контроллерах. Представьте, что у вас есть два способа разместить комментарий; вы неизбежно получите дублирование кода. Такой тип поведения относится к модели.

Предположим, вы хотите отслеживать количество комментариев, которые делает пользователь, и присудить достижение за 100 комментариев. У вас могут быть следующие модели:

class User < ActiveRecord::Base
  has_many :comments
  has_many :achievements

  def award(achievement)
    achievements << achievement.new
  end

  def awarded?(achievement)
    achievements.count(:conditions => { :type => achievement }) > 0
  end
end

class Achievement < ActiveRecord::Base
  belongs_to :user
end

class Comment < ActiveRecord::Base
  belongs_to :user
end

class CommentAchievement < Achievement
  def self.check_conditions_for(user)
    # Check if achievement is already awarded before doing possibly expensive
    # operations to see if the achievement conditions are met.
    if !user.awarded?(self) and user.comments.size > 100
      user.award(self)
    end
  end
end

Различные достижения являются подклассами модели Achievement и используют наследование одной таблицы, так что они хранятся только в одной таблице. Подклассы могут содержать всю логику, необходимую для каждого отдельного достижения. Вы также можете сохранить в этой модели дополнительную информацию, например дату присуждения достижения. Чтобы убедиться, что база данных отклоняет повторяющиеся достижения, вы можете создать индекс UNIQUE в столбцах типа и user_id .

CommentAchievement.check_conditions_for (user) можно вызвать в любое время. Вы можете создать фоновое задание, которое время от времени запускается, или вы можете создать наблюдателя:

# app/models/comment_achievement_observer.rb
class CommentAchievementObserver < ActiveRecord::Observer
  observe :comment

  def after_create(comment)
    CommentAchievement.check_conditions_for(comment.user)
  end
end

# config/environment.rb
config.active_record.observers = :comment_achievement_observer

Вышеупомянутое - лишь одна идея о том, как это сделать, конечно, могут быть и другие. Код - это просто пример, я его еще не тестировал. Надеюсь, это вам поможет.

Вы можете создать фоновое задание, которое время от времени запускается, или вы можете создать наблюдателя:

# app/models/comment_achievement_observer.rb
class CommentAchievementObserver < ActiveRecord::Observer
  observe :comment

  def after_create(comment)
    CommentAchievement.check_conditions_for(comment.user)
  end
end

# config/environment.rb
config.active_record.observers = :comment_achievement_observer

Вышеупомянутое - лишь одна идея о том, как это сделать, конечно, могут быть и другие. Код - это просто пример, я его еще не тестировал. Надеюсь, это вам поможет.

Вы можете создать фоновое задание, которое время от времени запускается, или вы можете создать наблюдателя:

# app/models/comment_achievement_observer.rb
class CommentAchievementObserver < ActiveRecord::Observer
  observe :comment

  def after_create(comment)
    CommentAchievement.check_conditions_for(comment.user)
  end
end

# config/environment.rb
config.active_record.observers = :comment_achievement_observer

Вышеупомянутое - лишь одна идея о том, как это сделать, конечно, могут быть и другие. Код - это просто пример, я его еще не тестировал. Надеюсь, это вам поможет.

52
ответ дан 27 November 2019 в 01:34
поделиться

Очень хорошее решение, molf.

Я развернул это в плагин / гем с генераторами для новых достижений:

http://github.com/paulca/paths_of_glory

Счастливых достижений!

18
ответ дан 27 November 2019 в 01:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: