我有一个简单的图书馆系统,用户可以在其中登录并留下书籍评论,我想做的是让用户每本书只能留下一条评论,如果他们已经为该书留下了评论,那么该评论将显示在编辑表单上,以便用户可以更改它。有没有办法做到这一点?我猜这会涉及使用belongs_to和has_one但我不太确定。我认为与此相关的模型是:product.rb,user.rb和reviews.rb,我也有produts_controller,reviews_controller和users_controller。我已经在按照建议尝试first_or_initalize但无法使其工作?有人可以帮忙吗?
Reviews_controller.rb:
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
def new
if logged_in?
@review = Review.where(user_id: params[:user_id]).first_or_initialize
@review = Review.new(product_id: params[:id], user_id: User.find(session[:user_id]))
session[:return_to] = nil
else
session[:return_to] = request.url
redirect_to login_path, alert: "You need to login to write a review"
end
end
def create
@review = Review.new(review_params)
if @review.save
product = Product.find(@review.product.id)
redirect_to product, notice: 'Your review was successfully added.'
else
render action: 'new'
end
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if @review.update(review_params)
format.html { redirect_to @review, notice: 'Review was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @review.errors, status: :unprocessable_entity }
end
end
end
评论.rb:
class Review < ActiveRecord::Base
belongs_to :product
validates :review_text, :presence => { :message => "Review text: cannot be blank ..."}
validates :review_text, :length => {:maximum => 2000, :message => "Review text: maximum length 2000 characters"}
validates :no_of_stars, :presence => { :message => "Stars: please rate this book ..."}
结束
我会做这样的模型关系:
用户.rb
has_many :reviews
产品.rb
has_many :reviews
评论.rb
belongs_to :user
belongs_to :product
# This does the magic for the multiple validation
validates_uniqueness_of :user_id, :scope => :product_id, :message=>"You can't review a product more than once", on: 'create'
如您所见,我会让用户可以有很多评论,一个产品也可以有很多评论,但是如果你有一个用户想要对已经有该用户评论的产品进行评论,它将引发验证错误,它不会让用户对同一产品发表两次评论。
如果用户在尝试对他已经进行评论的产品进行新评论时必须看到他的评论,您可以做这样的事情,这会将用户对产品的评论搜索到评论模型中,如果它找到它会加载它,但是当该用户没有对产品的评论时,它将加载新的评论:
控制器/review_controller.rb
def new
if current_user
@review = Review.where(user_id: current_user.id, product_id: params[:product_id]).first_or_initialize
if @review.id.present?
render 'edit'
end
end
end
我希望它对:D有所帮助!