บล็อกการสร้างออบเจ็กต์หลายรายการในคลาส

ฉันจะจำกัดวัตถุของคลาสใด ๆ ให้เป็นคลาสเดียวได้อย่างไร ชั้นเรียนของฉันดูเหมือนว่า:

class Speaker
  include Mongoid::Document
  field :name, :type => String
end

ฉันแค่อยากจะยกตัวอย่างหนึ่งของวิทยากร วิธีหนึ่งคือการเพิ่มการตรวจสอบความถูกต้องซึ่งจะตรวจสอบจำนวนอ็อบเจ็กต์ที่มีอยู่แล้วในคลาส Speaker มีวิธีทับทิมในการทำสิ่งต่าง ๆ หรือไม่?


person Prabesh Shrestha    schedule 19.08.2011    source แหล่งที่มา
comment
หากคุณต้องการลำโพงเพียงตัวเดียว ควรเก็บไว้ใน db หรือไม่ ฉันจะแตกมันเป็นไฟล์ปรับแต่ง   -  person rubish    schedule 19.08.2011
comment
@rubish ฉันต้องอนุญาตให้ผู้ดูแลระบบเปลี่ยนค่า ฉันจะทำอย่างไรได้อย่างมีประสิทธิภาพหากไม่บันทึกลงในฐานข้อมูล   -  person Prabesh Shrestha    schedule 20.08.2011
comment
แล้วการตรวจสอบตามที่ฉันเขียนไว้ด้านล่างล่ะ?   -  person Sławosz    schedule 22.08.2011
comment
@Slawosz ฉันคิดว่านั่นเป็นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้ตอนนี้ แค่รอว่าฉันสามารถหาวิธีแก้ปัญหาที่ดีกว่านี้ได้หรือไม่   -  person Prabesh Shrestha    schedule 22.08.2011


คำตอบ (6)


แล้วการใช้โมดูล Singleton ล่ะ

person Frank Schmitt    schedule 19.08.2011
comment
ฉันจะเปลี่ยนค่าได้อย่างไร ฉันยังต้องการให้คุณค่ายังคงอยู่ - person Prabesh Shrestha; 19.08.2011
comment
หากเป็น Admin USER ที่เปลี่ยนค่า คำตอบนี้ก็จะมีกลิ่นโค้ด มิฉะนั้นโปรดดู stackoverflow.com/questions/137975/ สำหรับการถกเถียงกันอย่างยาวนาน - person Alec Wenzowski; 01.09.2011

ในกรณีนี้ ฉันจะเขียนการตรวจสอบที่ถูกต้อง:

validate :only_one

def only_one
   errors.add(:base, "Only one Speaker can exist") if self.count > 0 
end
person Sławosz    schedule 19.08.2011
comment
การดำเนินการนี้จะล้มเหลวหากมีบันทึกอยู่แล้วและคุณกำลังอัปเดต - person Steven Soroka; 26.08.2011
comment
จุดดี แต่คุณสามารถเขียนได้: validate :only_one, :on =› :create - person Sławosz; 26.08.2011
comment
NoMethodError: undefined method `count` for #<Speaker:0x28f18e1d> - self ในบริบทของวิธีการตรวจสอบคืออินสแตนซ์ ดังนั้น self.count จำเป็นต้องเปลี่ยนเป็น Speaker.count หรือ self.class.count - person Abe Voelker; 03.04.2013

ฉันแนะนำให้ใช้คลาส/โมดูลที่ปรับแต่งเพื่อจัดเก็บค่าการกำหนดค่าแทนที่จะนำค่าของคุณเองไปไว้บนโมเดลวานิลลา ActiveRecord

ฉันใช้สำเนาเก่าของปลั๊กอิน rails-settings พร้อมการแก้ไขแบบกำหนดเองบางส่วน (ยังคงใช้งานได้ดีอยู่ ในราง 3) นอกจากนี้ยังมีข้อเสนอรูปแบบต่างๆ มากมายที่แสดงอยู่ใน Github ดังนั้นอย่าลังเลที่จะเลือกดูและเลือก

person Jeremy Weathers    schedule 24.08.2011

เหตุใดจึงไม่จัดเตรียมออบเจ็กต์ Speaker เริ่มต้น และเพียงไม่ให้มีการดำเนินการของคอนโทรลเลอร์เพื่อสร้างหรือลบ

ดูเหมือนวิธีแก้ปัญหาที่ง่ายที่สุดในตอนนี้

person Steven Soroka    schedule 26.08.2011

ฉันเห็นคุณกำลังใช้ Mongoid

ฟังก์ชันที่คุณร้องขอไม่สามารถใช้งานได้โดยใช้การตรวจสอบ mongoid

ดังนั้นคุณจะต้องเขียนของคุณเอง before_validation เป็น การโทรกลับที่รองรับ และวิธี Speaker.all.count แบบลูกโซ่ ใช้ได้กับโมเดลของคุณ

class Speaker
  include Mongoid::Document
  field :name, :type => String
  before_validation(:ensure_has_only_one_record, :on => :create)
  def ensure_has_only_one_record
    self.errors.add :base, "There can only be one Speaker." if Speaker.all.count > 0
  end
end

อย่างไรก็ตาม แนวทางปฏิบัติที่ดีที่สุดคือการวางการตั้งค่าคีย์/ค่าทั้งหมดไว้ในตารางเดียว< /ก>.

person Alec Wenzowski    schedule 27.08.2011

การใช้โมดูล Singleton และการเอาชนะวิธีการเล็กน้อย ฉันเชื่อว่ามันใช้งานได้และปลอดภัยสำหรับเธรด (บน Ruby 1.8):

class Speaker 

  include Singleton
  include Mongoid::Document
  field :name, :type => String

  @@singleton__instance__ = nil
  @@singleton__mutex__ = Mutex.new

  def self.instance
    return @@singleton__instance__ if @@singleton__instance__
    @@singleton__mutex__.synchronize {
      return @@singleton__instance__ if @@singleton__instance__
      @@singleton__instance__ = self.first
      @@singleton__instance__ ||= new()
    }
    @@singleton__instance__
  end

  def destroy
    @@singleton__mutex__.synchronize {
      super
      @@singleton__instance__ = nil
    }
  end

end
person andersonvom    schedule 27.08.2011
comment
ขอบคุณที่ชี้ให้เห็นว่า ย้อนกลับไปใน Ruby 1.8 นั่นไม่ใช่กรณีนี้ - person andersonvom; 08.04.2013