سؤال

كيف يمكنني تحقيق ما يلي ؟ لدي اثنين من نماذج (بلوق القراء) و الانضمام إلى الجدول من شأنها أن تسمح لي أن N:M العلاقة بينهما:

class Blog < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :readers, :through => :blogs_readers
end

class Reader < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :blogs, :through => :blogs_readers
end

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader
end

ما أريد أن أفعله الآن هو إضافة القراء على مدونات مختلفة.الشرط ، على الرغم من أن أنا يمكن فقط إضافة القارئ إلى بلوق مرة واحدة.لذا يجب أن لا يكون أي التكرارات (نفس readerID, نفس blogID) في BlogsReaders الجدول.كيف يمكنني تحقيق ذلك ؟

السؤال الثاني هو كيف يمكنني الحصول على قائمة من بلوق أن القراء ليس اشتركت بالفعل (على سبيل المثاللملء القائمة المنسدلة اختر القائمة ، والتي يمكن استخدامها لإضافة قارئ إلى آخر بلوق)?

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

المحلول

وماذا عن:

Blog.find(:all,
          :conditions => ['id NOT IN (?)', the_reader.blog_ids])

والقضبان يعتني بجمع هويات بالنسبة لنا مع الطرق الرابطة! :)

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ ClassMethods.html

نصائح أخرى

أبسط حل هو في صلب القضبان:

 class Blog < ActiveRecord::Base
     has_many :blogs_readers, :dependent => :destroy
     has_many :readers, :through => :blogs_readers, :uniq => true
    end

    class Reader < ActiveRecord::Base
     has_many :blogs_readers, :dependent => :destroy
     has_many :blogs, :through => :blogs_readers, :uniq => true
    end

    class BlogsReaders < ActiveRecord::Base
      belongs_to :blog
      belongs_to :reader
    end

ملاحظة إضافة :uniq => true الخيار has_many المكالمة.

كما قد ترغب في النظر في has_and_belongs_to_many بين بلوق قارئ, إلا إذا كان لديك بعض السمات الأخرى التي ترغب في الانضمام إلى نموذج (التي لا حاليا).هذا الأسلوب أيضا :uniq opiton.

لاحظ أن هذا لا يمنعك من إنشاء الإدخالات في الجدول, ولكنها لا تضمن عند الاستعلام جمع يمكنك الحصول على واحد فقط من كل كائن.

التحديث

في القضبان 4 طريقة للقيام بذلك هو عن طريق نطاق الكتلة.تغييرات أعلاه.

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { uniq }, through: :blogs_readers
end

class Reader < ActiveRecord::Base
 has_many :blogs_readers, dependent: :destroy
 has_many :blogs, -> { uniq }, through: :blogs_readers
end

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader
end

تحديث القضبان 5

استخدام uniq في نطاق كتلة سوف يسبب خطأ NoMethodError: undefined method 'extensions' for []:Array.استخدام distinct بدلا من ذلك :

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { distinct }, through: :blogs_readers
end

class Reader < ActiveRecord::Base
 has_many :blogs_readers, dependent: :destroy
 has_many :blogs, -> { distinct }, through: :blogs_readers
end

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader
end

وهذا ينبغي أن تأخذ الرعاية من سؤالك الأول:

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader

  validates_uniqueness_of :reader_id, :scope => :blog_id
end

القضبان 5.1 الطريقة

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { distinct }, through: :blogs_readers
end

class Reader < ActiveRecord::Base
 has_many :blogs_readers, dependent: :destroy
 has_many :blogs, -> { distinct }, through: :blogs_readers
end

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader
end

والجواب على هذا الرابط يوضح كيفية تجاوز "<<" طريقة لتحقيق ما كنت تبحث عن دون رفع استثناءات أو إنشاء طريقة منفصل: <لأ href = "https://stackoverflow.com/questions/1315109 / القضبان-لغة إلى تجنب التكرار في ولديها كثير من خلال "> القضبان لغة لتجنب التكرار في has_many: من خلال

وأنا أفكر شخص ما سوف يأتي جنبا إلى جنب مع إجابة أفضل من هذا.

the_reader = Reader.find(:first, :include => :blogs)

Blog.find(:all, 
          :conditions => ['id NOT IN (?)', the_reader.blogs.map(&:id)])

[عدل]

ويرجى الاطلاع على الإجابة جوش أدناه. انها وسيلة للذهاب. (كنت أعرف أن هناك طريقة أفضل من هناك؛)

ويقول الجواب العليا حاليا لاستخدام uniq في بروك:

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { uniq }, through: :blogs_readers
end

ولكن هذا جزاء العلاقة في صفيف ويمكن كسر الأشياء التي تتوقع لتنفيذ عمليات على علاقة، وليس صفيف.

إذا كنت تستخدم distinct وتبقي على كعلاقة:

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { distinct }, through: :blogs_readers
end

وأسهل طريقة هي تسلسل العلاقة في صفيف:

class Blog < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :readers, :through => :blogs_readers
  serialize :reader_ids, Array
end

وبعد ذلك عند تعيين قيم للقراء، كنت تطبيقها ك

blog.reader_ids = [1,2,3,4]

عند تعيين العلاقات بهذه الطريقة، يتم إزالة التكرارات تلقائيا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top