সম্পর্কের মাধ্যমে কীভাবে একটি has_many থেকে অনন্য রেকর্ড প্রদর্শন করবেন?


106

আমি বিস্মিত হয়েছি, রেল 3-এর সম্পর্কের মধ্য দিয়ে একটি has_many থেকে অনন্য রেকর্ড প্রদর্শন করার সর্বোত্তম উপায় কী।

আমার কাছে তিনটি মডেল রয়েছে:

class User < ActiveRecord::Base
    has_many :orders
    has_many :products, :through => :orders
end

class Products < ActiveRecord::Base
    has_many :orders
    has_many :users, :through => :orders
end

class Order < ActiveRecord::Base
    belongs_to :user, :counter_cache => true 
    belongs_to :product, :counter_cache => true 
end

আসুন বলতে দিন যে কোনও গ্রাহক তাদের শো পৃষ্ঠায় আদেশ করেছেন এমন সমস্ত পণ্যকে আমি তালিকাবদ্ধ করতে চাই।

তারা কয়েকটি পণ্যকে একাধিকবার অর্ডার দিয়ে থাকতে পারে, সুতরাং আমি অর্ডার সংখ্যার ভিত্তিতে অবতরণ র‌্যাঙ্ক ক্রমে প্রদর্শন করতে কাউন্টার_ ক্যাশে ব্যবহার করছি।

তবে, যদি তারা একাধিকবার কোনও পণ্য অর্ডার করে থাকে তবে আমার নিশ্চিত করতে হবে যে প্রতিটি পণ্য কেবল একবারে তালিকাভুক্ত হয়েছে।

@products = @user.products.ranked(:limit => 10).uniq!

যখন কোনও পণ্যের জন্য একাধিক অর্ডার রেকর্ড রয়েছে তখন কাজ করে, তবে কোনও পণ্য কেবল একবার অর্ডার করা হলে ত্রুটি উত্পন্ন করে। (স্থান নির্ধারণ কাস্টম বাছাই ফাংশন অন্য কোথাও সংজ্ঞায়িত)

আর একটি বিকল্প হ'ল:

@products = @user.products.ranked(:limit => 10, :select => "DISTINCT(ID)")

আমি নিশ্চিত নই যে আমি এখানে সঠিক পন্থায় আছি।

অন্য কেউ এই মোকাবেলা করেছে? আপনি কোন বিষয়গুলির বিরুদ্ধে এসেছিলেন? ইউনিকের মধ্যে পার্থক্য সম্পর্কে আমি আরও কোথায় জানতে পারি! এবং DISTINCT ()?

সম্পর্কের মাধ্যমে has_many এর মাধ্যমে অনন্য রেকর্ডের একটি তালিকা তৈরি করার সর্বোত্তম উপায় কী?

ধন্যবাদ

উত্তর:


235

আপনি কি has_many সমিতিতে ইউনিক বিকল্পটি নির্দিষ্ট করার চেষ্টা করেছেন:

has_many :products, :through => :orders, :uniq => true

থেকে পাগল ডকুমেন্টেশন :

:uniq

যদি সত্য হয় তবে সংগ্রহ থেকে নকলগুলি বাদ দেওয়া হবে। এর সাথে: মাধ্যমে মাধ্যমে কার্যকর।

বিক্রয় 4 এর জন্য আপডেট করুন:

4 কারাগারে, has_many :products, :through => :orders, :uniq => trueহ্রাস করা হয়। পরিবর্তে, আপনার এখন লেখা উচিত has_many :products, -> { distinct }, through: :orders। আরও তথ্যের জন্য অ্যাক্টিভেকর্ড অ্যাসোসিয়েশন ডকুমেন্টেশন সম্পর্কিত সম্পর্কের মাধ্যমে: has_many এর স্বতন্ত্র বিভাগটি দেখুন । কার্ট মুয়েলারকে তার মন্তব্যে এটি উল্লেখ করার জন্য ধন্যবাদ।


6
পার্থক্যটি এতটা নয় যে আপনি মডেল বা নিয়ামকটিতে সদৃশগুলি সরিয়ে ফেলুন বা আপনি বরং: আপনার অ্যাসোসিয়েশনে ইউনিক বিকল্পটি (আমার উত্তর হিসাবে দেখানো হয়েছে) বা এসকিউএল ডিআইএসএনসিটি স্টেম্ট (যেমন has_many: পণ্য,: মাধ্যমে =>: অর্ডার ব্যবহার করুন) ,: সিলেক্ট করুন>> "DISTINCT পণ্য। *)। প্রথম ক্ষেত্রে, সমস্ত রেকর্ডগুলি পাওয়া যায় এবং রেলগুলি আপনার জন্য সদৃশগুলি সরিয়ে দেয় later পরবর্তী ক্ষেত্রে, ডিবি থেকে কেবল নন-অনুলিপি রেকর্ডগুলি নেওয়া হয় যাতে এটি আরও ভাল পারফরম্যান্সের প্রস্তাব দিতে পারে আপনার যদি একটি বড় ফলাফল সেট থাকে
মব্রাইনিং

68
4 কারাগারে, has_many :products, :through => :orders, :uniq => trueহ্রাস করা হয়। পরিবর্তে, আপনার এখন লেখা উচিত has_many :products, -> { uniq }, through: :orders
কার্ট মুয়েলার

8
দ্রষ্টব্য যে -> {ইউনিক this এই অর্থে -> {স্বতন্ত্র} apidock.com/rails/v4.1.8/ActtiveRecord/QueryMethods/uniq এর জন্য কেবল একটি এলিফ আছে এটি এসকিউএলে রুবি নয়
ইঞ্জিনিয়ার

5
যদি আপনার সাথে বিরোধ DISTINCTএবং ORDER BYক্লজগুলি পাওয়া যায় তবে আপনি সর্বদা ব্যবহার করতে পারেনhas_many :products, -> { unscope(:order).distinct }, through: :orders
fagiani

1
ধন্যবাদ @ ফাগিয়ানি এবং যদি আপনার মডেলটিতে একটি জেসন কলাম থাকে এবং আপনি পিএসকিএল ব্যবহার করেন তবে এটি আরও জটিল হয়ে যায় এবং has_many :subscribed_locations, -> { unscope(:order).select("DISTINCT ON (locations.id) locations.*") },through: :people_publication_subscription_locations, class_name: 'Location', source: :locationঅন্যথায় আপনি যেমন পান rails ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: could not identify an equality operator for type json
তেমন

43

নোটটি যেটি 4 রেল হিসাবে uniq: trueবৈধ বিকল্পগুলি থেকে সরানো হয়েছে has_many

4 রেলগুলিতে আপনাকে এই জাতীয় আচরণ কনফিগার করার সুযোগ সরবরাহ করতে হবে। স্কোপগুলি ল্যাম্বডাসের মাধ্যমে সরবরাহ করা যায়, যেমন:

has_many :products, -> { uniq }, :through => :orders

রেল গাইডটি আপনার এবং আপনার সম্পর্কের প্রশ্নগুলি ফিল্টার করতে স্কোপগুলি ব্যবহার করতে পারবেন এমন অন্যান্য উপায়ে section.৩.৩ বিভাগে স্ক্রোল করুন:

http://guides.rubyonrails.org/association_basics.html#has-many-association-reference


4
5.1 undefined method 'except' for #<Array....uniq.distinct
রেলগুলিতে

5

আপনি ব্যবহার করতে পারে group_by। উদাহরণস্বরূপ, আমার কাছে একটি ফটো গ্যালারী শপিং কার্ট রয়েছে যার জন্য আমি চাইছি যে ছবিটির মাধ্যমে আইটেমগুলি বাছাই করা হোক (প্রতিটি ফটো একাধিক বার এবং বিভিন্ন আকারের প্রিন্টে অর্ডার করা যেতে পারে)। এরপরে এটি পণ্য (ফটো) সহ কী হিসাবে একটি হ্যাশ ফেরত দেয় এবং প্রতিবার আদেশ হওয়ার সাথে সাথে ছবির (বা না) প্রসঙ্গে তালিকাভুক্ত করা যায়। এই কৌশলটি ব্যবহার করে, আপনি প্রতিটি প্রদত্ত পণ্যের জন্য অর্ডার ইতিহাসের আউটপুট পেতে পারেন। এটি এই প্রসঙ্গে আপনার পক্ষে সহায়ক কিনা তা নিশ্চিত নন তবে আমি এটি বেশ কার্যকর বলে মনে করেছি। এখানে কোড

OrdersController#show
  @order = Order.find(params[:id])
  @order_items_by_photo = @order.order_items.group_by(&:photo)

@order_items_by_photo তারপরে এমন কিছু দেখাচ্ছে:

=> {#<Photo id: 128>=>[#<OrderItem id: 2, photo_id: 128>, #<OrderItem id: 19, photo_id: 128>]

সুতরাং আপনি যেমন কিছু করতে পারে:

@orders_by_product = @user.orders.group_by(&:product)

তারপরে আপনি যখন আপনার দৃষ্টিতে এটি পান, কেবল এই জাতীয় কিছু দিয়ে লুপ করুন:

- for product, orders in @user.orders_by_product
  - "#{product.name}: #{orders.size}"
  - for order in orders
    - output_order_details

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

আপনি যা করার চেষ্টা করছেন তার জন্য এটি ওভারকিল হতে পারে তবে পরিমাণের সাথে কাজ করার জন্য এটি আপনাকে কয়েকটি দুর্দান্ত বিকল্প (যেমন তারিখের আদেশ দেওয়া ইত্যাদি) দেয়।


বিস্তারিত উত্তর দেওয়ার জন্য ধন্যবাদ. এটি আমার প্রয়োজনের তুলনায় কিছুটা বেশি হতে পারে তবে তবুও শিখতে আকর্ষণীয় (আসলে আমি এটি অ্যাপ্লিকেশনটিতে অন্য কোথাও ব্যবহার করতে পারি)। এই পৃষ্ঠায় উল্লিখিত বিভিন্ন পদ্ধতির জন্য কর্মক্ষমতা সম্পর্কে আপনার মতামতগুলি কী?
অ্যান্ডি হার্ভে

2

6 রেলগুলিতে আমি পুরোপুরি কাজ করতে পেরেছি:

  has_many :regions, -> { order(:name).distinct }, through: :sites

কাজের অন্য উত্তরগুলির কোনও উত্তর পেলাম না।


5.2+ রেলপথে একই
গ্লেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.