Я столкнулся с той же проблемой, но решение, которое мне помогло, было:
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
был тег баннера над моей навигационной панелью
Я согласен с вашей идеей использовать модель 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
Вышеупомянутое - лишь одна идея о том, как это сделать, конечно, могут быть и другие. Код - это просто пример, я его еще не тестировал. Надеюсь, это вам поможет.
Очень хорошее решение, molf.
Я развернул это в плагин / гем с генераторами для новых достижений:
http://github.com/paulca/paths_of_glory
Счастливых достижений!