有没有办法可以使用可以使用erb重写HTML部分的rake任务或方法?

时间:2015-09-27 22:08:39

标签: ruby-on-rails ruby

很抱歉这个令人困惑的标题,但我会在这里详细说明。

好的,所以在我网站的用户索引页面上,我有一个热门热门歌曲列表。该列表按用户排名排序,并且此列表会随着每首歌曲汇总相对于彼此的排名变化而动态变化。

class SongratingsController < ApplicationController
 @Top100 = Rails.cache.read('Top100')
 lastSpot = @Top100.last

 def reCalcTop100
   @Top100 =    Song.where('num_stars > ?', 0 ).order('num_stars desc,  total_score desc').limit(100)
   Rails.cache.fetch('Top100'){@Top100}
 end

 def addRatingToSong
    userID = params[:uid].to_i
    songId = params[:sid].to_i 
    rVal = params[:valR].to_i
    @averageS = []
    songRate = Songrating.find_by(:user_id => userID, :song_id => songId)
    if songRate != nil
        oldScore = songRate.rating
        songRate.update_attributes(:rating => rVal)
        @song = Song.find(songId)
        score = @song.total_score - oldScore
        newScore = score + rVal 
        averageScore = newScore/@song.songratings_count
        @song.update_attributes(:total_score => newScore,:num_stars => averageScore)
        @averageS[0] = averageScore
        @averageS[1] = @song.songratings_count
    else
        Songrating.create!(:user_id => userID, :song_id => songId,:rating => rVal)
        @song = Song.find(songId)
        newScore = @song.total_score + rVal
        averageScore = newScore/@song.songratings_count
        @song.update_attributes(:total_score => newScore,:num_stars => averageScore)
        @averageS[0] = averageScore
        @averageS[1] = @song.songratings_count
    end

    if newScore > lastSpot.total_score && averageScore > lastSpot.num_stars
        reCalcTop100
    end

     if request.xhr?

     render :json => {
                       :starData =>  @averageS

                   }
     end


end

正如您在下面的这两张照片中所看到的,我有一个显示此列表的视图部分,但是现在我每次用户登录主页时都会生成列表。但由于此列表并非用户独有,我觉得我在浪费时间重新生成此列表。

enter image description here

enter image description here

理想情况下,我只想在top100列表更改时生成并编写静态HTML部分,但我真的不知道如何实现这一点。

感谢。

1 个答案:

答案 0 :(得分:1)

是的,只需使用erb

vars = OpenStruct.new({some_var: some_val})
rendered_html = ERB.new(File.read("#{Rails.root}/app/templates/embed_code.html.erb")).result(vars.instance_eval { binding })

这会将渲染的html放在render_html变量中,您可以将其写入文件或执行任何操作。这应该在ruby类或rake任务的背景下工作。

vars传递给模板,可以用作&lt;%= some_var%&gt;在模板中。

现在我已经回答了你的实际问题,我认为更好的解决方案就是使用Rails.cache来缓存渲染数据。

任何需要很长时间的事情都可以使用

进行缓存
result = Rails.cache.fetch "some_cache_key" do
  # things you want to cache
end

这将缓存块并将其返回到结果。如果将来存在未经过缓存的数据,它只会从缓存中返回,如果缓存为空或过时,它将重新执行该块并将其返回到结果中。

最后在控制器的上下文中,您可以使用动作缓存,这是更多的动手。

有关详细信息,请参阅:http://guides.rubyonrails.org/caching_with_rails.html