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

Ruby on Rails If a user has already added data for one product stop them from doing so again relationship

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

Review.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 ..."}

结束

我会做这样的模型关系:

user.rb

has_many :reviews

product.rb

has_many :reviews

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'

如您所见,我会让一个用户可以有很多评论,一个产品也可以有很多评论,但是如果您有一个用户想要对已经有评论的产品进行评论该用户将引发验证错误,并且不会让用户对同一产品发表两次评论。

如果用户在尝试对他已经发表评论的产品发表新评论时必须查看他的评论,您可以执行类似这样的操作,即搜索用户的评论将产品添加到评论模型中,如果发现它会加载它,但是当该用户没有对该产品进行评论时,它将加载新评论:

controllers/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!