我对Rails还是很陌生,并在一个实践项目实验室工作,但遇到一个问题,即视图渲染速度非常慢。 任何帮助都将不胜感激!
我也收到此错误:
SystemStackError (stack level too deep):
app/models/blogger.rb:23:in `popular_post'
app/views/bloggers/show.html.erb:13:in `_app_views_bloggers_show_html_erb__247812415140953454_70240453389320'
宝石文件
gem 'rails', '~> 5.1.6'
gem 'sqlite3'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'faker'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'capybara', '~> 2.13'
gem 'selenium-webdriver'
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
我的课程是Blogger,目标和张贴(Blogger -< Post >- Destination
)。下面是Blogger模型,显示页面和控制器的代码(除了Blogger索引,我还没有从事其他任何事情的代码,但是可以工作,只是一个列表)
blogger.rb
class Blogger < ApplicationRecord
has_many :destinations
has_many :posts, through: :destinations
validates :name, uniqueness: true
validates :age, numericality: { greater_than: 0, message: ": You're Too Young" }
validates :bio, length: { :minimum => 30 }
def self.average_age
ages = self.all.sum do |blogger|
blogger.age
end
(ages / self.all.count)
end
def total_likes
self.posts.sum do |post|
post.likes
end
end
def popular_post
self.posts.max_by do |a|
a.likes
end
end
def top_five
self.destinations.sort_by do |destination|
destination.post_count
end.take(5)
end
end
blogger显示页面
<h1> <%= @blogger.name %> </h1>
<br />
<p> Age: <%= @blogger.age %> </p>
<br />
<br />
<p> Bio: <%= @blogger.bio %> </p>
<br />
<br />
<%= link_to @blogger.popular_post.title, post_path(@blogger.popular_post) %>
<br />
<%= @blogger.top_five %>
blogger控制器
class BloggersController < ApplicationController
def index
@bloggers = Blogger.all
end
def show
@blogger = Blogger.find(params[:id])
end
def new
@blogger = Blogger.new
end
def create
@blogger = Blogger.create(blogger_params)
if @blogger.valid?
@blogger.save
redirect_to blogger_path(@blogger)
else
flash[:my_errors] = @blogger.errors.full_messages
redirect_to new_blogger_path
# render :new
end
end
private
def blogger_params
params.require(:blogger).permit(:name, :bio, :age)
end
end
答案 0 :(得分:1)
我认为您需要修改此方法
def popular_post
self.posts.max_by do |a|
a.likes
end
end
max_by
是Enumerable类的一种方法,您在Post类上调用它,因此它将无法正常工作。如果posts.order('likes DESC').first
是整数,我建议您使用类似likes
的东西。
还有一个很小的提示,您不需要在对象和类方法中使用所有self
。如果这是对象方法,Rails会假定您在对象上调用它;如果这是类方法,则假定您在关系上调用它。
答案 1 :(得分:0)
方法total_likes
,popular_post
和top_five
都通过假设您的关联是“数组”(枚举)来工作。尽管这确实适用于较小的示例,但它并不是最佳的。因为处理数组还需要先从数据库中加载完整的数组,然后再在一个完整的集(在内存中)本地进行计算。数据库最适合执行此类任务(查询)。
例如,最好将top_five
写入数据库以进行排序,然后仅获取前5个(最受欢迎)。
def top_five
destinations.order(post_count: :desc).limit(5)
end
(这假设:post_count
是数据库中的实际字段。
类似地,我们可以改进其他方法:
def total_likes
posts.sum(:likes)
end
仅使用数据库:这将启动一个查询,以返回博客作者所有帖子的喜欢总数。
def popular_post
posts.order(likes: :desc).limit(1).first
end
我们按降序排序,然后选择第一个。 limit 1
告诉我们只想检索一个项目,但是它仍然返回一个数组,因此我们要返回第一个项目。
这应该可以改善您的表现。