আমি কীভাবে স্বয়ংক্রিয়ভাবে জেলগুলিতে একটি has_many সম্পর্ক বাছাই করব?


96

এটিকে সত্যিই সাধারণ প্রশ্নের মতো মনে হচ্ছে তবে আমি এর উত্তর কোথাও দেখিনি।

রেলগুলিতে যদি আপনার থাকে:

class Article < ActiveRecord::Base 
  has_many :comments 
end 
class Comments < ActiveRecord::Base 
  belongs_to :article 
end

আপনি কেন এমন কিছু দিয়ে মন্তব্যগুলি অর্ডার করতে পারবেন না:

@article.comments(:order=>"created_at DESC")

আপনার যদি এটিকে প্রচুর রেফারেন্স করতে হয় এবং এমনকি লোকেরা এই জাতীয় জিনিসগুলি করে তবে নামযুক্ত স্কোপটি কাজ করে:

@article.comments.sort { |x,y| x.created_at <=> y.created_at }

তবে কিছু আমাকে বলে যে এটি সহজ হওয়া উচিত। আমি কী মিস করছি?


সতর্কতা অবলম্বন করুন, আপনি একটি অপ্রত্যাশিত পদ্ধতি ব্যবহার করছেন: @ আর্টিকেল ডটমেন্টস (পুনরায় লোড = মিথ্যা) একটি ক্যাশে-মিস করতে বাধ্য করা (কোনও সম্পর্কের পুনরায় লোড করার জন্য) for যদি আপনি একটি হ্যাশ সরবরাহ করেন তবে এটি @ আর্টিকেল ডটকমেন্টস (সত্য) এর সমান। .All (: অর্ডার => '...') ব্যবহার করতে ভুলবেন না। ইতিমধ্যে কয়েকবার আমার পা ভেঙে ফেলেছে।
মার্সেল জ্যাকওয়ার্থ

উত্তর:


152

আপনি has_manyনিজের উপর একটি বিকল্প দিয়ে খালি সংগ্রহের জন্য সাজানোর ক্রম নির্দিষ্ট করতে পারেন :

class Article < ActiveRecord::Base 
  has_many :comments, :order => 'created_at DESC'
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end

বা, যদি আপনি বাছাইয়ের একটি সহজ, অ-ডেটাবেস পদ্ধতি চান, সারণি_বাই ব্যবহার করুন :

article.comments.sort_by &:created_at

ক্রিয়াকলাপের সাথে যুক্ত করার পদ্ধতিটি ক্রমানুসারে সংগ্রহ করা:

article.comments.find(:all, :order => 'created_at DESC')
article.comments.all(:order => 'created_at DESC')

আপনার মাইলেজটি পৃথক হতে পারে: আপনি প্রথম স্থানটিতে কীভাবে ডেটা আনছেন এবং আপনার অ্যাপটি চালানোর জন্য আপনি কোন রুবি ব্যবহার করছেন তার উপর নির্ভর করে উপরের সমাধানগুলির পারফরম্যান্স বৈশিষ্ট্যগুলি বন্যভাবে পরিবর্তিত হবে।


ধন্যবাদ, "সমস্ত" সম্ভবত সবচেয়ে সহজ। ভাল জিনিস!
ব্রায়ান আর্মস্ট্রং

58
4 রেলগুলিতে, অর্ডার বিকল্পটি সরানো হয়েছে। -> { order(created_at: :desc) }পরিবর্তে একটি ল্যাম্বডা ব্যবহার করুন। দেখুন: stackoverflow.com/questions/18284606/...
d_rail

এই পাগল 4 অবচিত হয়েছে, দেখতে stackoverflow.com/questions/18284606/...
bjelli

42

4 রেল হিসাবে, আপনি এটি করবেন:

class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end

একটি জন্য has_many :throughসম্পর্ক যুক্তি অর্ডার গুরুত্বপূর্ণ (এটা দ্বিতীয় হতে হয়েছে):

class Article
  has_many :comments, -> { order('postables.sort' :desc) }, 
           :through => :postable
end

আপনি সবসময় একই আদেশ এক্সেস মন্তব্য করতে চাইবেন থাকলে কোনো প্রসঙ্গ ব্যাপার আপনার কাছে এর মাধ্যমে এই কাজ করতে পারে default_scopeমধ্যে Commentমত:

class Comment < ActiveRecord::Base 
  belongs_to :article 
  default_scope { order(created_at: :desc) }
end

তবে এই প্রশ্নটিতে আলোচিত কারণগুলির জন্য এটি সমস্যাযুক্ত হতে পারে ।

রেল 4 এর আগে আপনি orderসম্পর্কের কী হিসাবে নির্দিষ্ট করতে পারেন , যেমন:

class Article < ActiveRecord::Base 
  has_many :comments, :order => 'created_at DESC'
end 

জিম উল্লিখিত হিসাবে আপনি sort_byফলাফল আনার পরে আপনি ব্যবহার করতে পারেন যদিও আকারের কোনও ফলাফলের সেটগুলিতে এটি এসকিউএল / অ্যাক্টিভেকর্ডের মাধ্যমে অর্ডার দেওয়ার চেয়ে ধীরে ধীরে ধীরে ধীরে হবে (এবং আরও অনেক বেশি মেমরি ব্যবহার করবে)।

আপনি যদি এমন কিছু করছেন যেখানে কোনও কারণে ডিফল্ট অর্ডার যুক্ত করা জটিল হয় বা আপনি কিছু ক্ষেত্রে আপনার ডিফল্টটিকে ওভাররাইড করতে চান তবে আনার ক্রিয়ায় এটি নির্দিষ্ট করা তুচ্ছ ial

sorted = article.comments.order('created_at').all

4
আনার ক্রিয়াতে আমি কোথায় এটি নির্দিষ্ট করতে পারি? আমি কি মডেলটিতে কোনও পদ্ধতিকে ওভাররাইড করব?
উইট

@ উইট - আপনি .order()গত উদাহরণের মতো পদ্ধতি চেইনে যুক্ত করতে পারেন । এই আপনি কি জিজ্ঞাসা করছেন?
ম্যাট স্যান্ডার্স

আমি দুঃখিত. আমি কী অর্জন করতে চাইছিলাম তা মনে করতে পারছি না।
উইট

4
পলিমারফিক উদাহরণের মাধ্যমে has_many এখানে সুপার সহায়ক!
বিজয়

7

আপনি যদি রেল ২.৩ ব্যবহার করছেন এবং এই বস্তুর সমস্ত সংগ্রহের জন্য একই ডিফল্ট ক্রমটি ব্যবহার করতে চান তবে আপনি আপনার সংগ্রহটি অর্ডার করতে ডিফল্ট_স্কোপ ব্যবহার করতে পারেন।

class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end

তারপরে ফোন দিলে

@students = @class.students

আপনার ডিফল্ট_স্কোপ অনুযায়ী সেগুলি অর্ডার করা হবে। খুব সাধারণ অর্থে টিবিএইচ হ'ল ডিফল্ট স্কোপগুলির একমাত্র সত্যই ভাল ব্যবহার।


4 রেল হিসাবে এটি অনুগত নয়। সঠিক রেলস 4 সিনট্যাক্সের জন্য এই সমাধানটি দেখুন: স্ট্যাকওভারফ্লো
কিস ব্রিগস

6

আপনি নিজের অবজেক্টগুলি পেতে এবং সেগুলিও সাজানোর জন্য অ্যাক্টিভেকর্ডের সন্ধানের পদ্ধতিটি ব্যবহার করতে পারেন।

  @article.comments.find(:all, :order => "created_at DESC")

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


4
অথবা সাধারণভাবে সংক্ষেপে পদ্ধতি @ article.comments.all (: অর্ডার => 'created_at DESC')
এরিক

0

এবং যদি আপনার কিছু অতিরিক্ত যুক্তি যেমন dependent: :destroyবা যা কিছু পাস করার প্রয়োজন হয় তবে আপনার ল্যাম্বদার পরে এইগুলি যুক্ত করা উচিত:

class Article < ActiveRecord::Base 
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.