استخدام HasCustomFields في إضافة

لدي نموذج في ملحق. النموذج هو Pfaffmananger::Server، والجدول هو pfaffmanager_servers. لأسباب معينة، أريد حقولًا مخصصة لهذا النموذج (أتوقع وجود طرق لأغراض معينة لتمديد بيانات الخادم قد تُستخدم فقط لعدد قليل من الحالات، ولا أريد وجود عدد هائل من الحقول غير المستخدمة في الغالب في النموذج).

إليك هجرة إنشاء الجدول:

class CreatePfaffmanagerServerCustomField < ActiveRecord::Migration[6.0]
  def change
    create_table :pfaffmanager_server_custom_fields do |t|
      t.integer :server_id, null: false
      t.string :name, limit: 256, null: false
      t.text :value
      t.timestamps null: false
    end
    add_index :pfaffmanager_server_custom_fields, [:server_id, :name]
  end
end

إذا استخدمت pfaffmanager_server_id بدلاً من server_id، فإن الهجرة تفشل لأنها لا تستطيع العثور على server_id. ولكن عندما أستخدم pfaffmanager_server_id كاسم للحقل، وعند محاولة حفظ خادم بعد إنشاء حقل مخصص، أحصل على:

  Pfaffmanager::ServerCustomField Load (0.4ms)  SELECT "pfaffmanager_server_custom_fields".* FROM "pfaffmanager_server_custom_fields" WHERE "pfaffmanager_server_custom_fields"."server_id" = 1
   (0.2ms)  ROLLBACK
PG::UndefinedColumn: ERROR:  column "pfaffmanager_server_id" of relation "pfaffmanager_server_custom_fields" does not exist
LINE 1: INSERT INTO pfaffmanager_server_custom_fields (pfaffmanager_...
    

إذن، إذا كان الحقل في الهجرة هو pfaffmanager_server_id، تفشل الهجرة، وإذا كان اسم الحقل هو server_id، يفشل الحفظ.

أنا ألقي نظرة على save_custom_fields في concerns/has_custom_fields.rb، لكنني لم أستطع تحديد ما إذا كان هناك طريقة ما لتجاوز ذلك.

هل هناك شيء يمكنني فعله بخلاف إعادة هيكلة كل شيء لاستخدام server بدلاً من pfaffmanager_server؟

هل قمت أيضًا بتحديث استدعاء add_index للإشارة إلى pfaffmanager_server_id؟

شكرًا جزيلاً لك، ديفيد!

نعم. قد يكون هذا هو مشكلتي. أظن أن هذه هي رسالة الخطأ التي كان ينبغي أن أدرجها. ويمكنني جعل عملية الترحيل تعمل مع أي من الحقلين (على الرغم من أنه عند استخدام pfaffmanager_server_id كاسم للحقل، يصبح اسم الفهرس أطول من 63 حرفًا، لذا يجب أن أستخدم اسمًا مختلفًا للفهرس).

دعني أحاول مرة أخرى.

استخدام server_id كاسم للحقل

class CreatePfaffmanagerServerCustomField < ActiveRecord::Migration[6.0]
  def change
    create_table :pfaffmanager_server_custom_fields do |t|
      t.integer :server_id, null: false
      t.string :name, limit: 256, null: false
      t.text :value
      t.timestamps null: false
    end
    add_index :pfaffmanager_server_custom_fields, [:server_id, :name]
  end
end

يفشل عند الحفظ مع:

 Pfaffmanager::ServerCustomField Load (3.8ms)  SELECT "pfaffmanager_server_custom_fields".* FROM "pfaffmanager_server_custom_fields" WHERE "pfaffmanager_server_custom_fields"."server_id" = 1
   (1.4ms)  ROLLBACK
PG::UndefinedColumn: ERROR:  column "pfaffmanager_server_id" of relation "pfaffmanager_server_custom_fields" does not exist
LINE 1: INSERT INTO pfaffmanager_server_custom_fields (pfaffmanager_...
                                                       ^

إذًا، فهو يبحث عن pfaffmanager_server_id. الآن، دعنا نستخدم pfaffmanager_server_id.

استخدام pfaffmanager_server_id كاسم للحقل

إليك عملية الترحيل:

class CreatePfaffmanagerServerCustomField < ActiveRecord::Migration[6.0]
  def change
    create_table :pfaffmanager_server_custom_fields do |t|
      t.integer :pfaffmanager_server_id, null: false
      t.string :name, limit: 256, null: false
      t.text :value
      t.timestamps null: false
    end
    add_index :pfaffmanager_server_custom_fields,
      [:pfaffmanager_server_id, :name],
      name: 'index_pfaffmanager_server_custom_fields_on_server_id_and_name'

  end
end

وهذا ما يحدث عندما أحاول s.custom_fields (كان ما سبق قادرًا على إرجاع nil لهذا لكنه لم يفشل حتى حاولت حفظ حقل مخصص). أقوم بتسجيل نوع الحقل المخصص هنا هنا):

 pry(main)> s.custom_fields
   (1.1ms)  SELECT "pfaffmanager_server_custom_fields"."name", "pfaffmanager_server_custom_fields"."value" FROM "pfaffmanager_server_custom_fields" WHERE "pfaffmanager_server_custom_fields"."server_id" = 1 ORDER BY id asc
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column pfaffmanager_server_custom_fields.server_id does not exist
LINE 1: ...e" FROM "pfaffmanager_server_custom_fields" WHERE "pfaffmana...
                                                             ^

from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/rack-mini-profiler-2.3.0/lib/patches/db/pg.rb:69:in `exec_params'
Caused by PG::UndefinedColumn: ERROR:  column pfaffmanager_server_custom_fields.server_id does not exist
LINE 1: ...e" FROM "pfaffmanager_server_custom_fields" WHERE "pfaffmana...
                                                             ^

الآن، هو يبحث عن server_id.

إذًا، يبدو أن custom_fields تريده بطريقة ما بينما save_custom_fields تريده بطريقة أخرى.

هل لا يهتم بما هو اسم الفهرس؟

لا أعتقد ذلك، لا

أعتقد أن النهج الثاني هو على الأرجح ما يجب السعي إليه (باستخدام pfaffman_server_id كاسم للعمود)

أتساءل ما إذا كان تجاوز هذه الطريقة قد يساعد:

يمكنك التحقق من القيمة الحالية في وحدة التحكم كما يلي:

Server.new.custom_fields_fk

إذا كانت القيمة هي server_id، فإنني أقترح تجاوز هذه الطريقة في نموذج Server الخاص بك:

class Server < ...
  def custom_fields_fk
    "pfaffman_server_id"
  end
end

أو ربما هذا الجزء :thinking:

شكرًا جزيلاً! إذن، Server.new.custom_fields_fk هو pfaffmanager_server_id إذا استخدمت pfaffmanager_serfver_id. لذا ربما يجب أن أستخدم server_id ثم أتعامل مع الاستبدال كما اقترحت سابقًا.

يبدو أن refresh_custom_fields_from_db تحاول استخدام الأسماء الخاطئة. أنا لا أفهم تمامًا ما الذي يفعله _custom_fields.order....

سأقوم بمعرفة ما يحدث إذا استخدمت server_id وإذا كان بإمكاني بعد ذلك تجاوز custom_fields_fk.

ها! لقد نجحت! شكرًا جزيلاً لك. قمت بالتبديل إلى server_id ثم قمت بذلك في نموذج server.rb الخاص بي:

    def custom_fields_fk
      @custom_fields_fk ||= "server_id"
    end

طالما أن هذا سيتجاوز ذلك فقط لهذا النموذج ولن يكسر user_custom_field وما شابه، فأعتقد أنني مستعد للبدء في ضرب رأسي مرة أخرى على Best way to enforce permissions--controller or constraint?. ثم يمكنني إضافة مسارات للقيام بأشياء مثل ملء حقول التخصيص الجديدة الخاصة بي بـ … شيء ما.

لا يمكنني أن أشكرك بما يكفي. على الأرجح أنك أنقذتني من يوم كامل. أنا مدين لك بـ :beer:!

عظيم! :tada: إذا كنت تستطيع التفكير في طريقة لجعلها أكثر عمومية، فسيكون ذلك بالتأكيد موضع ترحيب في طلب السحب (PR).

إذا خطر لي أي شيء سأبلغك أو أقدم طلب سحب (PR)، لكنني أعتقد أن إضافة تريد استخدام حقول مخصصة هي حالة نادرة جداً.

OM_fk_G.

بدا custom_fields_fk غبيًا لدرجة أنني افترضت أنه شيء كنت أنوي حذفه وسميته شيئًا غبيًا حتى أعرف أنه آمن لحذفه لاحقًا. لقد حان وقت لاحق، لذلك قمت بحذفه. وبعد ذلك فشلت مواصفاتي.

كان هناك حتى تعليق برابط لهذا الموضوع في الكود.