Rails-导致“堆栈太深”错误的唯一性

时间:2018-06-20 22:30:39

标签: ruby-on-rails ruby model unique

我目前正在使用API​​,在我的模型(称为Roast)中,它属于两个用户。一个是创建者,另一个是接收者。我当前的问题是,我只希望有一个实例,可以让这两个用户相互参与。我发现[文章] [1]就像我创建验证程序的问题一样,但是我的问题归结为堆栈问题。我不确定此循环在哪里发生,所以希望你们能为我解决这个问题。

# roast.rb

class Roast < ApplicationRecord
  validates :roast_creator, uniqueness: { scope: :roast_receiver }

  belongs_to :roast_creator, :class_name => :User, :foreign_key => :roast_creator
  belongs_to :roast_receiver, :class_name => :User, :foreign_key => :roast_receiver

  has_many :comments, :dependent => :destroy

  def last_responder

  end

  def last_reply
    return self.comments.order('comments.created_at DESC').limit(1).load[0] if self.comments.length > 0
  end
end

# user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  include DeviseTokenAuth::Concerns::User

  has_many :created_roasts, :class_name => :Roast, :foreign_key => :roast_creator
  has_many :received_roasts, :class_name => :Roast, :foreign_key => :roast_receiver

  has_many :comments
end

# roasts_controller
class RoastsController < ApplicationController
  before_action :set_roast, only: [:show, :update, :destroy, :respond]

  # GET /roasts
  # GET /roasts.json
  def index
    @roasts = Roast.all
  end

  # GET /roasts/1
  # GET /roasts/1.json
  def show
  end

  # POST /roasts
  # POST /roasts.json
  def create
    @roast = Roast.new
    puts "NEW"
    @roast.roast_creator = current_user
    puts "CREATOR SET"
    @roast.roast_receiver = User.find(params[:receiver])
    puts "RECEIVER SET"
    @comment = @roast.comments.new(user: current_user, content: params[:comment])
    puts "INITIAL COMMENT SET"

    if @roast.save && @comment.save
        puts "SAVE CREATED"
        render :show, status: :created, location: @roast
    else
      render json: @roast.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /roasts/1
  # PATCH/PUT /roasts/1.json
  def update
    if @roast.update(roast_params)
      render :show, status: :ok, location: @roast
    else
      render json: @roast.errors, status: :unprocessable_entity
    end
  end

  # DELETE /roasts/1
  # DELETE /roasts/1.json
  def destroy
    if(@roast.creator == current_user)
      @roast.destroy
    end
  end

  def respond
    if (current_user.id == @roast.creator.id || current_user.id == @roast.receiver.id)
      @comment = @roast.comments.create(user: current_user, content: params[:comment])

      if(@comment.save)
        render :show, status: :created, location: @roast
      else
        render json: @comment.errors, status: :unprocessable_entity
      end
    else
      render json: { error: "Current user is not a creator or a receiver of this particular roast." }, status: :unprocessable_entity
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_roast
      @roast = Roast.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
end

确切的错误是:

SystemStackError (stack level too deep):

app/controllers/roasts_controller.rb:27:in `create'

感谢您提供的任何见解!

1 个答案:

答案 0 :(得分:2)

您已使用以下两个关联配置了循环:

 belongs_to :roast_creator, :class_name => :User, :foreign_key => :roast_creator
 belongs_to :roast_receiver, :class_name => :User, :foreign_key => :roast_receiver

具体来说,foreign_key选项。这告诉Rails调用方法roast_receiver以获取外键值,该外键值将调用名为roast_receiver association ,其外键值为roast_receiver它将称为关联...等等,等等,等等。

此处的foreign_key选项应指向roast_receiver_id,而不是roast_receiver

belongs_to :roast_creator, :class_name => :User, :foreign_key => :roast_creator_id
belongs_to :roast_receiver, :class_name => :User, :foreign_key => :roast_receiver_id

但是Rails会根据关联的名称自动为您执行此操作,因此实际上您可以只使用这两行:

belongs_to :roast_creator, :class_name => :User
belongs_to :roast_receiver, :class_name => :User