Ruby on Rails 如果用户已经为一个产品添加了数据,则阻止他们再次这样做关系



我有一个简单的图书馆系统,用户可以在其中登录并留下书籍评论,我想做的是让用户每本书只能留下一条评论如果他们已经为该书留下了评论,那么该评论将显示在编辑表单上,以便用户可以更改它。有没有办法做到这一点?我猜这会涉及使用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有所帮助!

最新更新