我的Informations
模型具有plain_keywords
属性。更新此属性后,我想预编译我的SASS样式表,因为有一个SASS变量是根据此属性计算的。
This question似乎与我的相似,所以我这样做了:
的Gemfile
gem 'rake'
配置/初始化/ rake.rb
Rake.load_rakefile Rails.root.join('Rakefile')
应用程序/模型/ informations.rb
require 'rake'
class Informations < ApplicationRecord
after_save :precompile, if: :plain_keywords_changed?
private
def precompile
Rake::Task['assets:precompile'].invoke
end
end
更新precompile
属性时实际调用plain_keywords
方法,但我的样式表看起来没有变化。
你有什么想法吗?
编辑:
要回答问题我为什么要这样做?,plain_keywords
属性中包含的关键字会被CSS(SASS)动画化以使其滚动。但是动画需要有一个$keywords-length
SASS变量来计算,以便完全同质并且每个关键字的持续时间相同。
我的研究结果表明,每次更新此属性时,预编译样式表实际上是错误的。
所以我创建了一个stylesheets
控制器,其keywords
动作。它只生成我的CSS动画的动态部分。从控制器编译SASS真的很难(也许可能更慢)所以我决定直接生成CSS:
class StylesheetsController < ApplicationController
def keywords
length = Informations.get.keywords.length
duration = 2.0
transition = 0.4
height = 40
animation_duration = (duration + transition)*length
css = '.keywords strong {animation: keyword '+animation_duration.to_s+'s infinite}'
length.times do |n|
css += '.keywords strong:nth-of-type('+(n + 1).to_s+'){animation-delay:'+(-n*(transition + duration)).to_s+'s}'
end
css += '@keyframes keyword{'
[
{
p: 0,
properties: {
opacity: 0,
transform: 'translateY('+((-height).to_s)+'px) rotateX(90deg)',
:'transform-origin' => 'center bottom'
}
},
{
p: transition/animation_duration,
properties: {
opacity: 1,
transform: 'translateY(0) rotateX(0)',
:'transform-origin' => 'center bottom'
}
},
{
p: (transition + duration)/animation_duration,
properties: {
opacity: 1,
transform: 'translateY(0) rotateX(0)',
:'transform-origin' => 'center top'
}
},
{
p: (transition*2 + duration)/animation_duration,
properties: {
opacity: 0,
transform: 'translateY('+height.to_s+'px) rotateX(-90deg)',
:'transform-origin' => 'center top'
}
},
{
p: 1,
properties: {
opacity: 0,
transform: 'translateY('+height.to_s+'px) rotateX(-90deg)',
:'transform-origin' => 'center top'
}
}
].each do |keyframe|
css += (keyframe[:p]*100).to_s+'%{'
css += keyframe[:properties].to_a.map{ |v| v.join ':' }.join ';'
css += '}'
end
css += '}'
render text: css, content_type: 'text/css'
end
end