سؤال

هل من الممكن تعيين معرف كائن المجال بشكل صريح في Bootstrap.groovy الخاص بـ Grails (أو في أي مكان، في هذا الصدد)؟

لقد حاولت ما يلي:

new Foo(id: 1234, name: "My Foo").save()

و:

def foo = new Foo()
foo.id = 1234
foo.name = "My Foo"
foo.save()

ولكن في كلتا الحالتين، عندما أقوم بطباعة نتائج Foo.list() في وقت التشغيل، أرى أن كائني قد حصل على معرف 1، أو أيًا كان المعرف التالي في التسلسل.

يحرر:يحدث هذا في Grails 1.0.3، وعندما أقوم بتشغيل تطبيقي في "dev" باستخدام قاعدة بيانات HSQL المضمنة.

يحرر:قدمت تشانويت حل واحد جيد أدناه.ومع ذلك، كنت أبحث بالفعل عن طريقة لتعيين المعرف دون تغيير طريقة إنشاء المعرف الخاص بنطاقي.هذا في المقام الأول للاختبار:أود أن أكون قادرًا على تعيين أشياء معينة على قيم المعرفات المعروفة إما في اختبار التمهيد الخاص بي أو setUp(), ، ولكن لا يزال بإمكانك استخدام الزيادة التلقائية أو التسلسل في الإنتاج.

هل كانت مفيدة؟

المحلول

نعم، مع تعيين GORM يدويًا:

class Foo {
  String name
  static mapping = {
    id generator:'assigned'
  }
}

وسيقوم المقتطف الثاني (وليس الأول) بالمهمة (لن يتم تعيين المعرف عند تمريره عبر المُنشئ).

نصائح أخرى

ما انتهى بي الأمر باستخدامه كحل بديل هو عدم محاولة استرداد الكائنات بمعرفها.لذلك بالنسبة للمثال الوارد في السؤال، قمت بتغيير كائن المجال الخاص بي:

class Foo {
  short code /* new field */
  String name

  static constraints = {
    code(unique: true)
    name()
  }
}

ثم استخدمت enum للاحتفاظ بجميع القيم الممكنة للتعليمات البرمجية (والتي تكون ثابتة)، وسيتم استردادها Foo الكائنات عن طريق القيام ب Foo.findByCode() بقيمة التعداد المناسبة (بدلاً من استخدام Foo.get() بالمعرف كما أردت أن أفعل سابقًا).

إنه ليس الحل الأكثر أناقة، لكنه نجح بالنسبة لي.

كبديل، على افتراض أنك تقوم باستيراد البيانات أو ترحيل البيانات من تطبيق موجود, ولأغراض الاختبار، يمكنك استخدام الخرائط المحلية داخل ملف Bootstrap.فكر في الأمر وكأنه ملف import.sql ذو فوائد؛-)

باستخدام هذا النهج:

  1. لن تحتاج إلى تغيير قيود المجال الخاصة بك فقط للاختبار ،
  2. سيكون لديك مسار ترحيل تم اختباره من البيانات الموجودة، و
  3. سيكون لديك شريحة بيانات جيدة (أو شريحة كاملة) لاختبارات التكامل المستقبلية

هتافات!

def init = { servletContext ->

    addFoos()
    addBars()

}

def foosByImportId = [:]
private addFoos(){
    def pattern = ~/.*\{FooID=(.*), FooCode=(.*), FooName=(.*)}/
    new File("import/Foos.txt").eachLine {
        def matcher = pattern.matcher(it)
        if (!matcher.matches()){
            return;
        }

        String fooId = StringUtils.trimToNull(matcher.group(1))
        String fooCode = StringUtils.trimToNull(matcher.group(2))
        String fooName = StringUtils.trimToNull(matcher.group(3))

        def foo = Foo.findByFooName(fooName) ?: new Foo(fooCode:fooCode,fooName:fooName).save(faileOnError:true)
        foosByImportId.putAt(Long.valueOf(fooId), foo) // ids could differ
    }
}

private addBars(){
    ...
    String fooId = StringUtils.trimToNull(matcher.group(5))
    def foo = foosByImportId[Long.valueOf(fooId)]
    ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top