ruby 多级(3级)嵌套模型无法更新记录,显示“记录已成功更新”消息

hsgswve4  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(92)

我仍然在努力获得Rails,请容忍我。我有一个多层嵌套模型关系,包括:报价单,哪个HAS_ONE RealServiceGroup,哪个HAS_MANY RealSegment(s),这反过来又HAS_MANY RealQuoteLine(s)一旦用户确定将使用哪个服务组,所有TESE均从其原型模型复制(为了简单起见,省略了原型模型,只认为真实的是从原型模型复制的)所以复制按预期进行,真实的被创建好了,但是为了完成报价,RealQuoteLine的“quantity”和“unit_price”属性需要编辑(更新)和持久化。我的问题是,它不会坚持新的价值观。下面是相关代码:app/models/quotation.rb

class Quotation < ApplicationRecord
  belongs_to :request
  has_one :service_group, class_name: "ServiceGroup"
  has_one :real_service_group, class_name: "RealServiceGroup", dependent: :destroy

  enum :state, %i[en_proceso enviada facturada comentada fondos], default: :en_proceso

  # after_create :get_real_service_group

  accepts_nested_attributes_for :service_group, reject_if: ->(attributes){ attributes['title'].blank? }, allow_destroy: true
  accepts_nested_attributes_for :real_service_group, reject_if: ->(attributes){ attributes['title'].blank? }, allow_destroy: true

  def get_real_service_group(service_group)
    real_service_group = RealServiceGroup.new(service_group.attributes.except('id'))
    real_service_group.title += ' (work) '
    real_service_group.quotation_id = self.id
    real_service_group.save
    service_group.segments.each do |segment|
      real_segment = real_service_group.real_segments.build(segment.attributes.except('id', 'service_group_id').merge(real_service_group_id: real_service_group.id))
      real_segment.title += ' (work) '
      real_segment.save
      segment.quote_lines.each do |quote_line|
        real_quote_line = real_segment.real_quote_lines.build(quote_line.attributes.except('id', 'segment_id').merge(real_segment_id: real_segment.id))
        real_quote_line.save
      end
    end
    real_service_group.save
    self.real_service_group = real_service_group
    save
  end
end

app/models/真实的_service_group.rb

class RealServiceGroup < ApplicationRecord
  belongs_to :quotation, inverse_of: :real_service_group, optional: true
  has_many :real_segments, class_name: 'RealSegment', dependent: :destroy

  accepts_nested_attributes_for :real_segments, reject_if: ->(attributes){ attributes['title'].blank? }, allow_destroy: true
end

app/models/真实的_segment.rb

class RealSegment < ApplicationRecord
  belongs_to :real_service_group
  has_many :real_quote_lines, dependent: :destroy

  accepts_nested_attributes_for :real_quote_lines, reject_if: ->(attributes){ attributes['quote_concept'].blank? }, allow_destroy: true
end

app/models/真实的_quote_line.rb

class RealQuoteLine < ApplicationRecord
  belongs_to :real_segment, class_name: "RealSegment"
end

app/controllers/quotation_controller.rb(只需#create、#update和#quotation_params)

def create
    @quotation = Quotation.new(quotation_params)
    console
    respond_to do |format|
      if @quotation.save
        service_group = ServiceGroup.find(params[:quotation][:service_group_id])
        @quotation.get_real_service_group(service_group)
        format.html { redirect_to work_quotation_url(@quotation), notice: 'Se ha creado exitosamente la Cotización.' }
        format.json { render :show, status: :created, location: @quotation }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @quotation.errors, status: :unprocessable_entity }
      end
    end
  end
def update
    respond_to do |format|
      ActiveRecord::Base.transaction do
        if @quotation.update(quotation_params)
          format.html { redirect_to quotation_url(@quotation), notice: "Quotation was successfully updated." }
          format.json { render :show, status: :ok, location: @quotation }
        else
          format.html { render :edit, status: :unprocessable_entity }
          format.json { render json: @quotation.errors, status: :unprocessable_entity }
        end
      end
    end
  end
def quotation_params
      params.require(:quotation).permit(
        :request_id, :total, :state,
        real_service_group_attributes: {
          title: :title,
          tax_rate: :tax_rate,
          retencion: :retencion,
          usd_exchange_rate: :usd_exchange_rate,
          base_padron: :base_padron,
          impuesto_general_importacion: :impuesto_general_importacion,
          padron_importadores: :padron_importadores,
          real_segments_attributes: [
            :id,
            :title,
            :currency,
            :iva,
            :retention,
            real_quote_lines_attributes: [
              :id,
              :quote_concept,
              :quantity,
              :unit_price
            ]
          ]
        }
      )
    end

config/routes.rb

Rails.application.routes.draw do
  resources :quote_lines
  resources :service_groups
  resources :segments
  resources :real_quote_lines
  resources :quotations do
    collection do
      get 'line_fields'
    end
    member do
      get 'work'
    end
  end
  resources :requests
  resources :clients
  resources :notes
  resources :quotation_concepts

  get 'start_assign' => 'requests#unassigned'
  get 'request_inbox' => 'requests#inbox'
  
  get  'logout' => 'sessions#destroy'
  get  'login'  => 'sessions#new'
  post 'login'  => 'sessions#create'
  
  resources :users
  root 'static_pages#main'
  
end

app/views/quotations/work.html.erb(这还没有完成,我需要添加Stimulus代码来计算小计和quotation -cotizacion- total)

<div>
  <h3>Ahora se completará la cotización</h3>
</div>
<table class="show-table" >
  <tr>
    <td class="fw-light">Cotización:</td>
    <td><%= @quotation.id %></td>
  </tr>
  <tr>
    <td class="fw-light">Requerimiento:</td>
    <td><%= @quotation.request.description %></td>
  </tr>
  <tr>
    <td class="fw-light">Cliente:</td>
    <td><%= @quotation.request.client.name %></td>
  </tr>
</table>

<%= form_with(model: @quotation) do |form| %>
  <% @quotation.real_service_group.tap do |rsg| %>
    <% total_cotizacion = 0 %>
    <table class="cot-table">
        <thead>
          <tr>
            <th>Servicio:</th>
            <th colspan="3"><%= rsg.title %></th>
          </tr>
          <% rsg.real_segments.each do |rs| %>
            <tr>
              <th>Segmento:</th>
              <th><%= rs.title %></th>
              <th>Moneda:</th>
              <th><%= rs.currency %></th>
            </tr>
            <tr>
              <th>Concepto</th>
              <th>Cantidad</th>
              <th>Precio Unitario</th>
              <th>importe</th>
            </tr>
        </thead>
            <% subtotal_segmento = 0 %>
            <% rs.real_quote_lines.each do |rql| %>
              <tr data-controller="linea-cotizacion">
                <td><%= rql.quote_concept %></td>
                <%= form.fields_for "real_service_group_attributes[real_segments_attributes][][real_quote_lines_attributes][]", rql do |quote_line_fields| %>
                    <% quote_line_fields.hidden_field :id %>
                    <td><%= quote_line_fields.number_field :quantity, data: { target: 'linea-cotizacion.quantity' } %></td>
                    <td>
                      <%= quote_line_fields.number_field :unit_price, 
                                                data: { 
                                                  target: 'linea-cotizacion.unitPrice',
                                                  action: 'focusout->linea-cotizacion#updateImporte'
                                                } %>
                    </td>
                    <%= content_tag(:td, '', id: 'importe', class: "fw-bold") %>
              </tr>
              <% end %> <%# fields_for %>
            <% end %> <%# rs.real_quote_lines %>
            <%# Aquí va el renglón para el subtotal del segmento %>
            <tr style="background-color: darkgray;">
              <td colspan="3" class="text-end">Subtotal</td>
              <td id="subtotal-segmento"><%= number_to_currency(subtotal_segmento) %></td>
            </tr>
        <% end %> <%# rs.real_segments %>
        <tr style="background-color: cadetblue;">
          <td colspan="3" class="text-end">Total</td>
          <td><%= number_to_currency(total_cotizacion) %></td>
        </tr>
    </table>
  <% end %> <%# rsg.real_service_group.tap %>
  <div>
    <%= form.submit "Guardar Cotización", class: "btn btn-primary" %>
  </div>
<% end %> <%# form_with %>

最后,这是我在控制台(日志)中得到的内容:

19:37:45 web.1  | Started PATCH "/quotations/58" for ::1 at 2023-08-31 19:37:45 -0600
19:37:45 web.1  | Processing by QuotationsController#update as TURBO_STREAM
19:37:45 web.1  |   Parameters: {"authenticity_token"=>"[FILTERED]", "quotation"=>{"real_service_group_attributes"=>{"real_segments_attributes"=>[{"real_quote_lines_attributes"=>{"117"=>{"quantity"=>"10", "unit_price"=>"134.0"}, "118"=>{"quantity"=>"10", "unit_price"=>"154.0"}, "119"=>{"quantity"=>"10", "unit_price"=>"15.0"}}}]}}, "commit"=>"Guardar Cotización", "id"=>"58"}
19:37:45 web.1  |   Quotation Load (0.2ms)  SELECT "quotations".* FROM "quotations" WHERE "quotations"."id" = $1 LIMIT $2  [["id", 58], ["LIMIT", 1]]
19:37:45 web.1  |   ↳ app/controllers/quotations_controller.rb:77:in `set_quotation'
19:37:45 web.1  |   TRANSACTION (0.1ms)  BEGIN
19:37:45 web.1  |   ↳ app/controllers/quotations_controller.rb:53:in `block (2 levels) in update'
19:37:45 web.1  |   RealServiceGroup Load (0.3ms)  SELECT "real_service_groups".* FROM "real_service_groups" WHERE "real_service_groups"."quotation_id" = $1 LIMIT $2  [["quotation_id", 58], ["LIMIT", 1]]
19:37:45 web.1  |   ↳ app/controllers/quotations_controller.rb:53:in `block (2 levels) in update'
19:37:45 web.1  |   Request Load (0.2ms)  SELECT "requests".* FROM "requests" WHERE "requests"."id" = $1 LIMIT $2  [["id", 12], ["LIMIT", 1]]
19:37:45 web.1  |   ↳ app/controllers/quotations_controller.rb:53:in `block (2 levels) in update'
19:37:45 web.1  |   TRANSACTION (0.1ms)  COMMIT
19:37:45 web.1  |   ↳ app/controllers/quotations_controller.rb:52:in `block in update'
19:37:45 web.1  | Redirected to http://localhost:3000/quotations/58
19:37:45 web.1  | Completed 302 Found in 15ms (ActiveRecord: 4.0ms | Allocations: 7940)
19:37:45 web.1  | 
19:37:45 web.1  | 
19:37:45 web.1  | Started GET "/quotations/58" for ::1 at 2023-08-31 19:37:45 -0600
19:37:45 web.1  | Processing by QuotationsController#show as TURBO_STREAM
19:37:45 web.1  |   Parameters: {"id"=>"58"}

这是我得到的截图:

我希望有人能帮助我

fdx2calv

fdx2calv1#

在视图模板中,如果有real_service_group[real_segments_attributes][][real_quote_lines_attributes][],请尝试添加_attributes,如下所示:

<%= form.fields_for "real_service_group_attributes[real_segments_attributes][][real_quote_lines_attributes][]", rql do |quote_line_fields| %>

相关问题