вложенные поля формы с использованием fields_for выдает ошибку «хэш определяется активной записью … с тем же именем»

#ruby-on-rails #ruby #stimulusjs

#ruby-on-rails #ruby #stimulusjs

Вопрос:

Я довольно новичок в rails, поэтому извините за мое невежество. Но в настоящее время у меня есть контроллер, который хранит «Результаты сканирования» для теоретического антивирусного сканера.

Модель сканирования, has_many Detections, которая представляет собой запись, содержащую хэш Sha256 и тип.

код выглядит следующим образом

 model/scan.rb

class Scan < ApplicationRecord
    has_many :detections, class_name: "detection", foreign_key: "d_id", :dependent => :destroy
    accepts_nested_attributes_for :detections
    validates :hostname, presence: true, uniqueness: { case_sensitive: true }, length: {maximum: 50, minimum: 1}, if: :hostname_not_empty
    
    

    def hostname_not_empty 
        if ( self.hostname != '' || self.hostname.nil? )
            return true
        end
        return errors.add(:scansErr, "Hostname is empty")
    end
end

  
 model/detections

class Detection < ApplicationRecord
  belongs_to :scan
  validates :hash, presence: true, length: {maximum: 64, minimum:64}, format: { with: /b[A-Fa-f0-9]{64}b/ }
  
  def new () 

  end 
  def new_record
  end
end

  

когда я пытаюсь создать шаблон для добавления новых сканирований в БД, я получаю эту ошибку hash is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name .

Я использую следующий шаблон, чтобы попытаться отобразить все это.

 views/dashboard/form.html.haml

...
= form_for :scans, url: dashboard_scan_create_path(params.to_unsafe_h.slice(:hostname)), :html => {:class => 'flex w-full flex-col scan-form' } do |s|
        %div.flex.w-full.relative
          #{s.text_field :hostname, :class => 'input border border-gray-400 appearance-none rounded w-full px-3 py-3 pt-8 pb-2 my-2 focus focus:border-indigo-600 focus:outline-none active:outline-none active:border-indigo-600' }
          #{s.label :hostname, :class => 'label absolute mb-0 -mt-2 pt-4 pl-3 leading-tighter text-gray-400 text-base mt-2 cursor-text'}
        %div.detections.flex.w-full.my-2{ 'data-controller' => 'detection-form' }
          %div.text-xl.font-bold Detections
          %template{"data-target" => "detection-form.template"}
            = s.fields_for :detections, Detection.new, child_index: "NEW_RECORD" do |d_form|
              = render "detection_fields", form: d_form
...

  
 views/dashboard/detections-fields.html.haml

= content_tag :div, class: "detection-fields" do
  .input.detection-field-input.d-flex.justtify-content-between.mb-2
    .col-11.pl-0
      = form.fields_for(:detection) do |detection_form|
        = detection_form.text_field :type
        = detection_form.text_field :hash
    .col-1
      = link_to "delete", "#", data: { action: "nested-form#remove_association" }
  = form.hidden_field :_destroy, as: :hidden


  

кто-нибудь может помочь мне понять, что я делаю неправильно.

Ответ №1:

Ошибка очевидна в том, что ActiveRecord::Core был определен метод hash , а ваша модель, Detection , имеет вызываемый конфликтующий атрибут hash .

Действие здесь заключается в переименовании hash атрибута вашей модели на что-то, что еще не реализовано / зарезервировано.

Например, если вы измените атрибут модели (и связанный с ним код, который его использует) на sha256 или sha , это позволит избежать конфликта.

Комментарии:

1. Большое спасибо!! Жаль, что я не написал это несколько часов назад. ты спас меня… Я не знаю, почему это не вычислялось

2. Все хорошо, надеюсь, это сработает для вас @JaSuperior, и если это так, я бы оценил, что вы отметили ответ как правильный!