দুটি অ্যাক্টিভেকর্ড :: সম্পর্কিত অবজেক্ট একত্রিত করুন


174

ধরুন আমার কাছে নিম্নলিখিত দুটি বস্তু রয়েছে:

first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation  = User.where(:last_name  => 'Fünke') # ActiveRecord::Relation

ActiveRecord::Relationউভয় শর্তযুক্ত একটি বস্তু উত্পাদন করতে দুটি সম্পর্ককে একত্রিত করা সম্ভব ?

দ্রষ্টব্য: আমি সচেতন যে এই আচরণটি পেতে আমি চাকাগুলি চেইন করতে পারি, আমি যে বিষয়ে সত্যই আগ্রহী তা হ'ল আমার দুটি পৃথক ActiveRecord::Relationবস্তু রয়েছে।


উত্তর:


202

যদি আপনি AND(ছেদ) ব্যবহার করে একত্রিত করতে চান তবে ব্যবহার করুন merge:

first_name_relation.merge(last_name_relation)

আপনি যদি OR(ইউনিয়ন) ব্যবহার করে সম্মিলন করতে চান তবে ব্যবহার করুন :or

first_name_relation.or(last_name_relation)

শুধু ActiveRecord মধ্যে 5+; 4.2 এর জন্য যেখানে বা ব্যাকপোর্টটি ইনস্টল করুন ।


কীভাবে যদি আমি ফলাফলটি এক ActiveRecord::Relationধরণের হতে চাই ?
নিউ আলেকজান্দ্রিয়া

1
@ নিউ আলেকজান্দ্রিয়া হ্যাঁ, সমস্ত ক্ষেত্রে, রেলগুলি আপনাকে বস্তুর শ্রেণীর বিষয়ে মিথ্যা বলছে।
অ্যান্ড্রু মার্শাল

77
মার্জ করার কোনও "ওআর" সংস্করণ আছে কি?
আর্কিলে

8
@ মিনহিম নিজেই সম্ভবত কারণ এটি আপনার দুটি সম্পর্কের একত্রিত হওয়ার আসল ফলাফল। নোট যে mergeএকটি সংযোগ নয়, মিলন নয়।
অ্যান্ড্রু মার্শাল

5
ভবিষ্যতের রেফারেন্সের জন্য, #orপদ্ধতিটি অ্যাক্টিভেকর্ডে যুক্ত করা হয়েছে :: ২০১৫ সালের জানুয়ারীতে সম্পর্কিত, এবং এটি রেল 5.0 এর অংশ হবে, যা ২০১৫ সালের শেষের দিকে প্রেরণ করবে It এটি ওআর অপারেটরটিকে যেখানে বা হ'ল ধারাগুলিকে একত্রিত করার অনুমতি দেয়। অফিসিয়াল রিলিজের আগে আপনার যদি প্রয়োজন হয় তবে আপনি হেড চেকআউট করতে পারেন। দেখুন মার্জ টানুন অনুরোধ # 16052 @Arcolye @AndrewMarshall @ আলডো-xoen-Giambelluca
ক্লডিও Floreani

37

রিলেশন অবজেক্টগুলিকে অ্যারেতে রূপান্তর করা যায়। এটি পরবর্তীতে তাদের উপর কোনও অ্যাক্টিভেকর্ড পদ্ধতি ব্যবহার করতে সক্ষম হতে অস্বীকার করে, তবে আমার দরকার হয়নি। আমি এটা করেছি:

name_relation = first_name_relation + last_name_relation

রুবি 1.9, রেল 3.2


আপডেট: করুণা এই তারিখ দ্বারা মার্জ না
ড্যানিয়েল মরিস

68
এটি অ্যারে হিসাবে কাজ করে না, এটি আপনার সম্পর্ককে অ্যারের সাথে রূপান্তর করে। তারপরে আপনি আর কোথাও () এর মতো অ্যাক্টিভেকর্ড পদ্ধতি ব্যবহার করতে পারবেন না ...
আগস্টিন রিডিংগার

1
আপনি যদি রিটার্ন টাইপ রিলেশনশিপ সম্পর্কে চিন্তা না করেন তবে আপনি একাধিক ফলাফল প্রথম_নাম_ সম্পর্কিত সাথে একত্রিত করতে পারেন last_name_relation। "|" অপারেটর পাশাপাশি একাধিক সম্পর্কের উপরও কাজ করে। ফলাফল মান একটি অ্যারে হয়।
মাইকেলজ

11
মূল প্রশ্নটি ছিল: "একটি অ্যাক্টিভেকর্ড :: রিলেশন অবজেক্টে উভয় শর্ত রয়েছে এমন দুটি উত্পাদনকে একত্রিত করা সম্ভব?" এই উত্তরটি একটি অ্যারে প্রদান করে ...
আদালতসমাজ

এটি বেশ কয়েকটি ক্ষেত্রে একটি দুর্দান্ত সমাধান। যদি আপনার কেবলমাত্র লুপটি রেকর্ডের একটি অঙ্ক প্রয়োজন হয় (উদাহরণস্বরূপ আপনি এটি কোনও অ্যারে বা অ্যাক্টিভেকর্ড :: সম্পর্ক যাচাই করেন না) এবং দুটি প্রশ্নের ওভারহেডকে কিছু মনে করেন না, এটি সমস্যাটি সুস্পষ্ট, সরল বাক্য গঠন দিয়ে সমাধান করে। আমি যদি এটি +2 করতে পারি!
ডেভিড হ্যাম্পি

21

mergeআসলে মত কাজ করে না OR। এটি কেবল ছেদ ( AND)

অ্যাক্টিভেকর্ড :: রিলেশন অবজেক্টগুলিকে একের সাথে একত্রিত করার জন্য আমি এই সমস্যার সাথে লড়াই করেছি এবং আমার পক্ষে কোনও কার্যনির্বাহী সমাধান খুঁজে পেল না।

এই দুটি সেট থেকে ইউনিয়ন তৈরি করার জন্য সঠিক পদ্ধতিটি অনুসন্ধানের পরিবর্তে, আমি সেটগুলির বীজগণিতের দিকে মনোনিবেশ করেছি। আপনি ডি মরগানের আইন ব্যবহার করে এটি বিভিন্ন উপায়ে করতে পারেন

অ্যাক্টিভেকর্ড একত্রিত করার পদ্ধতি সরবরাহ করে (এবং) এবং আপনি না পদ্ধতি বা কোনও_ও (নয়) ব্যবহার করতে পারেন।

search.where.none_of(search.where.not(id: ids_to_exclude).merge(search.where.not("title ILIKE ?", "%#{query}%")))

আপনার এখানে রয়েছে (A u B) '= A' ^ B '

আপডেট: আরও জটিল মামলার জন্য উপরের সমাধানটি ভাল। আপনার ক্ষেত্রে যেমন স্মথ যথেষ্ট হবে:

User.where('first_name LIKE ? OR last_name LIKE ?', 'Tobias', 'Fünke')

15

আমি অনেকগুলি বিজোড় পরিস্থিতিতে এমনকি রেলের অন্তর্নির্মিত আরেল ব্যবহার করে এটি সম্পাদন করতে সক্ষম হয়েছি ।

User.where(
  User.arel_table[:first_name].eq('Tobias').or(
    User.arel_table[:last_name].eq('Fünke')
  )
)

এটি আরেল এর বা ব্যবহার করে অ্যাক্টিভেকর্ড উভয় সম্পর্ককে একত্রিত করে ।


মার্জ, যেমন এখানে প্রস্তাবিত হয়েছিল, আমার পক্ষে কাজ করে না। এটি ফলাফল থেকে সম্পর্কের 2 র্থ সেট বাদ দিয়েছে।


2
এটি সেরা উত্তর, আইএমও। এটি OR টাইপ প্রশ্নের জন্য নির্দোষভাবে কাজ করে।
thekingoftruth

এটি নির্দেশ করার জন্য ধন্যবাদ, আমাকে অনেক সাহায্য করেছে। অন্যান্য উত্তরগুলি কেবলমাত্র ক্ষেত্রের ছোট্ট সাবসেটের জন্যই কাজ করে, তবে আইএন বিবৃতিতে দশ হাজার আইডির উপরে, পারফরম্যান্সটি খুব খারাপ হতে পারে।
onetwopunch

1
@ কিসব্রিগস- এটি সত্য নয়। আমি এটি রেল 4 এর সমস্ত সংস্করণে ব্যবহার করেছি
ফুট ড্যান

14

অ্যাক্টিভ_রেকার্ড_উনিউন নামে একটি রত্ন রয়েছে যা আপনি যা খুঁজছেন তা হতে পারে।

এটি ব্যবহারের উদাহরণ নিম্নলিখিত:

current_user.posts.union(Post.published)
current_user.posts.union(Post.published).where(id: [6, 7])
current_user.posts.union("published_at < ?", Time.now)
user_1.posts.union(user_2.posts).union(Post.published)
user_1.posts.union_all(user_2.posts)

ভাগ করে নেওয়ার জন্য ধন্যবাদ. এমনকি আপনার পোস্টের চার বছর পরেও আমার পক্ষে ইউনিয়ন তৈরি করার ransackএবং acts-as-taggable-onআমার ActiveRecordদৃষ্টান্ত অক্ষত রাখার একমাত্র সমাধান এটি ।
বেনিয়ামিন বোজকো

এই রত্নটি ব্যবহার করার সময়, আপনি মডেলটিতে স্কোপগুলি সংজ্ঞায়িত করতে পারলে কোনও অ্যাক্টিভেকর্ড :: ইউনিয়ন () কল দ্বারা রিলেশন রিটার্ন পাবেন না। রিডমিমে অ্যাক্টিভেকর্ডে ইউনিয়নের রাজ্যটি দেখুন।
ডিসিহিম্প

9

আপনি যদি প্রতিটি রেকর্ডের জন্য সনাক্তকারী পেতে প্ল্যাক ব্যবহার করেন, একসাথে অ্যারে যোগদান করুন এবং অবশেষে যোগদানকারী আইডির জন্য একটি জিজ্ঞাসা করুন: আমি এইভাবে এটি "পরিচালনা করেছি"

  transaction_ids = @club.type_a_trans.pluck(:id) + @club.type_b_transactions.pluck(:id) + @club.type_c_transactions.pluck(:id)
  @transactions = Transaction.where(id: transaction_ids).limit(100)

6

আপনার যদি ক্রিয়াকলাপের সম্পর্কগুলির একটি অ্যারে থাকে এবং সেগুলি সমস্ত মার্জ করতে চান তবে আপনি এটি করতে পারেন

array.inject(:merge)

array.inject(:merge)5.1.4 রেলগুলিতে অ্যাক্টিভেকর্ড সম্পর্কের অ্যারে জন্য কাজ করেনি। কিন্তু array.flatten!করেছেন।
zhisme

0

এটিকে জোর করে চাপিয়ে দিন:

first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation  = User.where(:last_name  => 'Fünke') # ActiveRecord::Relation

all_name_relations = User.none
first_name_relation.each do |ar|
  all_name_relations.new(ar)
end
last_name_relation.each do |ar|
  all_name_relations.new(ar)
end

"ন্যোমথোডেরর (অপরিজ্ঞাত পদ্ধতি` স্ট্রিংফাইকিজ "# # মাইমোডেল: 0 এক্স ...) এর জন্য রেল 3, মাইমোডেল.নোনটি মাইমোডেল.নে পরিবর্তন করার পরেও (1 = 2), যেহেতু রেল 3 এর 'কিছুই নেই' পদ্ধতি রয়েছে
জোসেফকে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.