首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何修复ActiveRecord::RecordNotSaved调用ActiveRecord#find_or_create_by时的错误

如何修复ActiveRecord::RecordNotSaved调用ActiveRecord#find_or_create_by时的错误
EN

Stack Overflow用户
提问于 2022-03-04 12:46:23
回答 2查看 129关注 0票数 1

我在一个网站上工作,每当有人在表单中忘记一个空字段时,我就会看到一个错误:

代码语言:javascript
运行
复制
You cannot call create unless the parent is saved

这是痕迹:

代码语言:javascript
运行
复制
Application Trace
app/views/technicians/offer_comments/_offer_comment.html.slim:1:in `_app_views_technicians_offer_comments__offer_comment_html_slim__1148413763742950523_70319840794240'
app/views/offer_comments/index.html.slim:2:in `_app_views_offer_comments_index_html_slim___917297770217289302_70319839456700'
app/views/shared/offers/_comments.html.slim:8:in `_app_views_shared_offers__comments_html_slim__3779418887197040636_70319839163900'
app/views/technicians/auctions/show.html.slim:98:in `block in _app_views_technicians_auctions_show_html_slim___1454306351028108654_70319829646100'
app/helpers/application_helper.rb:14:in `rescue in cache'
app/helpers/application_helper.rb:6:in `cache'
app/views/technicians/auctions/show.html.slim:1:in `_app_views_technicians_auctions_show_html_slim___1454306351028108654_70319829646100'
app/controllers/technicians/offers_controller.rb:54:in `update'

错误出现在此html.slim视图的第一行:

代码语言:javascript
运行
复制
- offer_comment.read_receipts.find_or_create_by user: current_user

.comment id="offer-#{offer_comment.offer_id}-comment-#{offer_comment.id}"
  .by
    - if offer_comment.user == current_user
      = t ".you"
    - else
      = t ".not_you"
    = " - "
    = t '.date', date: time_ago_in_words(offer_comment.created_at)

  .content
    = raw markdown offer_comment.content

有趣的是,此错误仅在我调用另一个对象offers时发生,该对象位于呈现前一段代码的主视图中:show.html.slim (最后一行)

代码语言:javascript
运行
复制
ul#customer-auction-tabs.tabs.clean.collapse(data-tabs)
            a#auctions-tabs-chevron href="#" 
              i#auctions-tabs-chevron-icon.fas.fa-chevron-up
            li.tabs-title class=chat_active_class
              a#chat-tab href="#chat" aria-selected="true"= t '.tabs.chat'
            li.tabs-title class=offer_active_class
              a#offers-tab href="#offers"= t '.tabs.offer'
            - if comments_count > 0
              li.tabs-title class=comments_active_class
                a#comments-tab href="#comments"= t '.tabs.comments'
            li.tabs-title class=other_active_class
              a#other-tab href="#other"= t '.tabs.other'

          .auctions.tabs-content data-tabs-content="customer-auction-tabs"
            #chat.tabs-panel class=chat_active_class
              = render partial: "shared/auctions/chat", locals: { auction: auction }

            #offers.tabs-panel class=offer_active_class
              = render partial: "shared/offers/new", locals: { offer: offer }

            #comments.tabs-panel class=comments_active_class
              = render partial: 'shared/offers/comments', locals: { offer: offer }

            #other.tabs-panel class=other_active_class
              - if auction.offers.count.zero?
                = t "ingen andre bud endnu"
              = render "shared/offers/other"
              .offers= render offers

我不明白这是如何工作的,因为find_or_create_by显然应该工作,即使对象还没有保存。

有人能帮我解决这个问题吗,最好避免在视图中使用像find_or_create_by这样的逻辑?

以下是报价模式的一部分:

代码语言:javascript
运行
复制
class Offer < ApplicationRecord
  has_paper_trail

  belongs_to :auction, -> { with_deleted }, counter_cache: true, touch: true
  belongs_to :technician, counter_cache: true, foreign_key: :technician_id

  has_one :settings, through: :technician

  has_many :comments, -> { order(created_at: :asc) }, class_name: "OfferComment"

  has_one :review, as: :target
  delegate :rating, to: :review, allow_nil: true
  delegate :rating_date, to: :review, allow_nil: true
  delegate :rating_comment, to: :review, allow_nil: true

  validates :description, presence: true
  validates :cents, presence: true, numericality: { only_integer: true, greater_than: 0 }

  validate :amount_validity

  scope :not_by, ->(technician) { where.not(technician: technician) }

下面还有控制器update操作,当使用null字段更新表单时会调用该操作:

代码语言:javascript
运行
复制
class Technicians::OffersController < Technicians::ApplicationController
  rescue_from ActiveRecord::RecordNotFound do
    render "technicians/auctions/lost", status: 404
  end

  def update
    offer.attributes = offer_params

    changed = offer.changed?

    if offer.save
      OfferUpdatedWorker.perform_async offer.id if changed
      flash[:info] = t(".success")
      redirect_to [:technicians, auction]
    else
      flash.now[:error] = t(".failure")
      render "technicians/auctions/show",
        locals: { auction: auction, offer: offer },
        status: 400
    end
  end

另一个需要注意的重要文件是拍卖控制器,它最初称为“技术人员/拍卖/展示”。

代码语言:javascript
运行
复制
  def show
    render(:lost) && return if lost?

    render :show, locals: {
      offers: sorted_o,
      auction: auction,
      #other: other,      
      offer: offer,
    } if stale? **cache_options(auction.id, auction.updated_at)
  end

  private
#=begin
    def sorted_o
      @sorted_o ||= begin
        field = (%w[cheapest closest guarantee] & [params[:sort]])[0].presence || "cheapest"

        case field
        when "closest"
          auction
            .offers
            .includes(:auction, :technician, :review)
            .sort_by { |o| distance(o.technician, auction) }
        when "guarantee"
          auction
            .offers
            .includes(:auction, :technician, :review)
            .joins(:settings)
            .order("technician_settings.guarantee desc")
        else
          auction
            .offers
            .includes(:auction, :technician, :review)
            .order(cents: :asc)
        end
      end
    end
#=end
    def offer
      @offer ||= auction.offers.by(current_user) ||
        auction.offers.new(technician: current_user)
    end
EN

Stack Overflow用户

发布于 2022-03-04 14:11:33

在创建属于offer_comment的read_receipt之前,您似乎需要保存它,这很有意义-- offer_comment在保存之前没有id。

这也许能帮你解决这个问题。

代码语言:javascript
运行
复制
offer_comment.tap(&:save).read_receipts.find_or_create_by user: current_user
票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71351633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档