【发布时间】:2021-04-26 18:51:57
【问题描述】:
我有一个发表评论的用户列表。我正在尝试使列表以不同的方式排序。我坚持按每个用户的最新评论对列表进行排序。
我目前的方法是制作模型范围。我就是不明白。
这是模型:
class User < ApplicationRecord
attr_accessor :password
validates_confirmation_of :password
validates :email, :presence => true, :uniqueness => true
validates :user_name, :presence => true, :uniqueness => true
before_save :encrypt_password
has_many :reviews
has_one_attached :avatar_pic
scope :users_most_recent, -> {(
select('users.id, users.user_name')
.joins(:reviews).where('reviews.updated_at')
.group('users.id')
.order('updated_at DESC')
)}
def self.user_reviews(user_id)
@user_reviews = Review.where(user_id: user_id).count
end
def self.user_ave_rating(user_id)
_average_reviews = []
_rev_count = 0
_new_average = 0.0
_average_reviews = Review.where(user_id: user_id)
_average_reviews.each do |average_review|
_rev_count += average_review.rating
end
_new_average = (_rev_count / _average_reviews.length.to_f).round(1)
end
def self.user_latest_review(user_id)
@latest_review = Review.where(user_id: user_id).where('created_at < ? ', Time.now).order('created_at DESC').first
if @latest_review.nil?
last_review = {}
else
last_review = @latest_review.created_at.strftime('%m-%d-%Y')
end
end
def encrypt_password
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password,password_salt)
end
def self.authenticate(email, password)
user = User.find_by "email = ?", email
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
end
这是控制器,索引是我要实现的地方:
class UsersController < ApplicationController
before_action :current_user, only: [:show, :edit, :update, :destroy]
def new
@user = User.new
end
def create
@user = User.new(user_params)
@user.avatar_pic.attach(params[:user][:avatar_pic])
if @user.save
flash[:notice] = "You've successfully signed up!"
session[:user_id] = @user.id
redirect_to "/"
else
flash[:alert] = "There was a problem signing up."
redirect_to '/signup'
end
end
def show
@user = current_user
render :show
end
def edit
@user = current_user
render :edit
end
def update
@user = current_user
if @user.update(user_params)
flash[:notice] = "Profile successfully updated!"
redirect_to user_path(@user)
else
render :edit
flash[:notice] = "Something went wrong. Please contact Mario's technical assistance staff."
end
end
def index
case
when params[:az]
@users = User.order('user_name').paginate(page: params[:page], per_page: 20)
when params[:za]
@users = User.order('user_name DESC').paginate(page: params[:page], per_page: 20)
when params[:high_rating]
"High Rating"
when params[:low_rating]
"Low Rating"
when params[:most_reviews]
"Most Reviews"
when params[:least_reviews]
"Least Reviews"
when params[:most_recent]
@users = User.users_most_recent.paginate(page: params[:page], per_page: 20)
when params[:least_recent]
"Least Recent"
else
@users = User.all.paginate(page: params[:page], per_page: 20)
end
render :index
end
private
def user_params
params.require(:user).permit(:email, :user_name, :password, :password_confirmation, :admin, :avatar_pic)
end
end
这是我的看法:
<p id="notice"><%= notice %></p>
<div class="sort-flex-wrapper">
<h1 class="center">Our Community</h1>
<div class="btn-group sort-button">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sort By
</button>
<div class="dropdown-menu">
<%= link_to "User Name A-Z", users_path(:az => 'az'), class: "dropdown-item" %>
<%= link_to "User Name Z-A", users_path(:za => 'za'), class: "dropdown-item" %>
<%= link_to "Highest Average Rating", users_path(:high_rating => 'high_rating'), class: "dropdown-item" %>
<%= link_to "Lowest Average Rating", users_path(:low_rating => 'low_rating'), class: "dropdown-item" %>
<%= link_to "Most Reviews", users_path(:most_reviews => 'most_reviews'), class: "dropdown-item" %>
<%= link_to "Least Reviews", users_path(:least_reviews => 'least_reviews'), class: "dropdown-item" %>
<%= link_to "Most Recent Review", users_path(:most_recent => 'most_recent'), class: "dropdown-item" %>
<%= link_to "Least Recent Review", users_path(:least_recent => 'least_recent'), class: "dropdown-item" %>
</div>
</div>
</div>
<div class="community-flex-container">
<% if @users.any? %>
<% @users.each do |user| %>
<div class="community-profile-card">
<div class="community-profile-flex">
<div class="community-profile-box1">
<% if user.avatar_pic.attached? %>
<%= image_tag user.avatar_pic, class:"avatar" %><br>
<% else %>
<%= image_tag 'generc_profile_pic.webp', class:"avatar", alt: 'Avatar Not Found ' %><br>
<% end %>
</div>
<div class="community-profile-box2">
<div class="community-column-box1">
<% if user.user_name? %>
<h3><%= user.user_name %></h3>
<% else %>
<h3>Guest User</h3>
<% end %>
</div>
<div class="community-column-box2">
<div class="community-align-stars">
<p>Average Rating: </p>
</div>
<div class="community-align-stars">
<div class="star-align">
<%= render partial: "shared/review_stars", locals: { review: User.user_ave_rating(user.id) } %>
</div>
</div>
</div>
<div class="community-column-box3">
<p>Number of Reviews: <%= User.user_reviews(user.id) %></p>
</div>
<div class="community-column-box4">
<% if User.user_latest_review(user.id) == {} %>
<p>Most Recent Review: None</p>
<% else %>
<p>Most Recent Review: <%= User.user_latest_review(user.id) %></p>
<% end %>
</div>
</div>
</div>
</div>
<% end %>
<% else %>
<p>There are no users (yet).</p>
<% end %>
</div>
<div class="pagination">
<%= will_paginate @reviews%>
</div>
【问题讨论】:
-
那么你所做的事情有什么不妥?
-
目前,我收到一条消息崩溃:ActiveRecord::StatementInvalid in Users#index PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type timestamp without time zone LINE 1: ...ews" ON "reviews"."user_id" = "users"."id" WHERE (reviews.up...
-
是的,您的查询中的位置没有意义,我在回答中将其删除。去哪里的目的是什么?
-
我有点过头了。这是一种失败的方法。
-
不用担心。我希望它现在可以工作
标签: ruby-on-rails ruby