অ্যাক্টিভেকর্ড বা কোয়েরি


180

কীভাবে আপনি রেলস 3 অ্যাক্টিভেকর্ডে একটি ওআর ক্যোয়ারি করেন। আমি যে উদাহরণগুলি পেয়েছি তার সবেমাত্র ও কোয়েরি রয়েছে।

সম্পাদনা: OR পদ্ধতিটি 5 টি পযন্ত থেকে উপলব্ধ Active


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

1
@ রায়ান0, আপনি ঠিক বলেছেন। আমরা অভিনব রত্ন এবং অন্যান্য জিনিস ব্যবহার করতে পারি, তবে আমাদের এই রত্নগুলি ভিতরে কী করছে এবং অন্তর্নিহিত প্রযুক্তি কী তা সম্পর্কে আমাদের সচেতন হওয়া উচিত, এবং রত্নের সাহায্য ছাড়াই অন্তর্নিহিত প্রযুক্তিগুলি ব্যবহার করা প্রয়োজন, যদি প্রয়োজন দেখা দেয় তবে কর্মক্ষমতা. রত্নগুলি নির্দিষ্ট সংখ্যক ব্যবহারকেশাগুলি মাথায় রেখে তৈরি করা হয় তবে এমন পরিস্থিতিতেও থাকতে পারে যেখানে আমাদের প্রকল্পের ব্যবহারের একটি আলাদা হতে পারে।
রুবিপ্রিন্স


1
পাঁচটি রেল, যেহেতু আইএমএইচও গ্রহণযোগ্য উত্তরটি গ্রেগ অলসেন সংস্করণ হওয়া উচিত:Post.where(column: 'something').or(Post.where(other: 'else'))
ফিলিপ ক্লেন

6
এই প্রশ্নের রুবি অন অন রেলস -3 এর ট্যাগ রয়েছে। কেন গৃহীত উত্তরগুলি কেবলমাত্র 5 টি রেলের সাথে সম্পর্কিত হবে?
iNtory

উত্তর:


109

আরেল ব্যবহার করুন

t = Post.arel_table

results = Post.where(
  t[:author].eq("Someone").
  or(t[:title].matches("%something%"))
)

ফলাফল এসকিউএল:

ree-1.8.7-2010.02 > puts Post.where(t[:author].eq("Someone").or(t[:title].matches("%something%"))).to_sql
SELECT     "posts".* FROM       "posts"  WHERE     (("posts"."author" = 'Someone' OR "posts"."title" LIKE '%something%'))

কিছুটা অগোছালো মনে হচ্ছে, তবে কমপক্ষে আমি স্ক্যুএল লিখছি না, যা ঠিক ভুল মনে হচ্ছে! আমি আরেল আরও ব্যবহার করা উচিত।
pho3nixf1re

54
মেকারিও
ম্যাকারিও

3
এসকিউএল-তে কোনও সমস্যা নেই। যে জিনিসটি ভুল হতে পারে তা হ'ল আমরা কীভাবে এসকিউএল স্ট্রিংটি এসকিউএল ইনজেকশন তৈরি করি । সুতরাং, একটি এসকিউএল ক্যোয়ারী সরবরাহ করার আগে আমাদের ব্যবহারকারীর ইনপুটটি স্যানিটাইজ করতে হবে যা ডাটাবেসের বিরুদ্ধে চালানো উচিত। এটি ওআরএম দ্বারা পরিচালিত হবে , এবং এগুলি প্রান্তের মামলাগুলি পরিচালনা করছে, যা আমরা মিস করি। সুতরাং, এটা সবসময় ব্যবহার করা বাঞ্ছনীয় ORM এসকিউএল কোয়েরি তৈরি করুন।
রুবিপ্রিন্স

5
এসকিউএল এর সাথে আর একটি সমস্যা হ'ল এটি ডেটাবেস অজ্ঞেয় নয়। উদাহরণস্বরূপ স্ক্লাইটের জন্য matchesউত্পাদন করা হবে LIKE(ডিফল্টরূপে সংবেদনশীল কেস) এবং পোস্টগ্রিসে ( ILIKEঅপারেটরের মতো স্পষ্ট কেস সংবেদনশীল প্রয়োজন)।
অ্যামিবে

1
টনিলিহ অ্যাক্টিভেকর্ড হুডের নিচে এসকিউএল ব্যবহার করছে। এটি এসকিউএল কোয়েরিগুলি লেখার জন্য একটি বাক্য গঠন যা এসকিউএল স্যানিটাইজেশন পরিচালনা করে এবং আপনার প্রশ্নগুলি ডিবি অজ্ঞেয়াদি তৈরি করে। একমাত্র ওভারহেড যেখানে রেলগুলি সিনট্যাক্সকে এসকিউএল কোয়েরিতে রূপান্তর করে। এবং এটি মিলি সেকেন্ডের বিষয় মাত্র। অবশ্যই আপনার সেরা পারফরম্যান্ট এসকিউএল কোয়েরিটি লিখতে হবে এবং এটিকে অ্যাক্টিভেকর্ড সিনট্যাক্সে রূপান্তর করার চেষ্টা করা উচিত। যদি এসকিউএলটিকে অ্যাক্টিভেকর্ড সিনট্যাক্সে উপস্থাপন করা যায় না, তবে আপনার সরল এসকিউএল জন্য যাওয়া উচিত।
রুবিপ্রিন্স

208

আপনি যদি একটি কলামের মান হিসাবে একটি ওআর অপারেটর ব্যবহার করতে চান, আপনি এতে একটি অ্যারে পাস করতে পারেন .whereএবং অ্যাক্টিভেকর্ডার ব্যবহার করবে IN(value,other_value):

Model.where(:column => ["value", "other_value"]

আউটপুট:

SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')

এটি ORএকটি একক কলামে একটি এর সমতুল্য অর্জন করা উচিত


13
এটি সবচেয়ে পরিষ্কার "রেলপথ" উত্তর, গ্রহণ করা উচিত ছিল
kunse

10
ধন্যবাদ @ কুনসে, এটি ঠিক 'ওআর' কোয়েরি নয়, তবে এটি এই পরিস্থিতির জন্য একই ফলাফল দেয়।
মৃতকর্ম

আপনি যদি সহায়তা করেন তবে সহায়তা করুন - stackoverflow.com/questions/15517286/…
প্রতীক বোথরা

79
এই দ্রষ্টব্যটি OR এর প্রতিস্থাপন নয় কারণ আপনি এইভাবে দুটি পৃথক কলাম ব্যবহার করতে পারবেন না।
fotanus

151

3 রেলগুলিতে, এটি হওয়া উচিত

Model.where("column = ? or other_column = ?", value, other_value)

এটিতে কাঁচা স্কয়ারও অন্তর্ভুক্ত রয়েছে তবে আমি ভাবি না যে অ্যাক্টিভেকর্ডে করার জন্য বা অপারেশন করার কোনও উপায় আছে। আপনার প্রশ্নটি কোন প্রশ্ন নয়।


40
এমনকি কাঁচা এসকিএল থাকলেও - এই বিবৃতিটি আমার কাছে আরেলের চেয়ে বেশি পরিষ্কার দেখাচ্ছে। এমনকি DRYer এমনকি।
jibiel

6
আপনার যদি শৃঙ্খলার দরকার হয়, অন্য টেবিলের সাথে মিল রয়েছে যার কলামগুলির একই কলামের নাম থাকতে পারে, আপনার এটি এটি ব্যবহার করা উচিতPage.where("pages.column = ? or pages.other_column = ?", value, other_value)
রুবিপ্রিন্স

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

58

রেলস / অ্যাক্টিভেকর্ডের একটি আপডেট সংস্করণ স্থানীয়ভাবে এই সিনট্যাক্সটিকে সমর্থন করতে পারে। এটি দেখতে অনুরূপ হবে:

Foo.where(foo: 'bar').or.where(bar: 'bar')

এই টান অনুরোধ https://github.com/rails/rails/pull/9052 তে উল্লিখিত হিসাবে

আপাতত, কেবলমাত্র নিম্নলিখিত কাজগুলি দিয়ে আঁকানো দুর্দান্ত:

Foo.where('foo= ? OR bar= ?', 'bar', 'bar')

আপডেট করুন: মতে https://github.com/rails/rails/pull/16052or বৈশিষ্ট্য পাগল উপলব্ধ হবে 5

আপডেট: বৈশিষ্ট্যটি রেল 5 শাখায় মার্জ করা হয়েছে


2
orএখন R টি রেল উপলভ্য রয়েছে তবে এইভাবে প্রয়োগ করা হবে না কারণ এটি 1 টি আর্গুমেন্ট পাস হওয়ার প্রত্যাশা করে। এটি একটি আরেল বস্তুর প্রত্যাশা করে। গৃহীত উত্তরটি দেখুন
এল'ম্যাগনিফিকো

2
orActiveRecord পদ্ধতি কাজ করে আপনি এটি সরাসরি ব্যবহার করছেন কিন্তু যদি এটি একটি সুযোগ যা পরে শৃঙ্খলিত করা হয় ব্যবহৃত হচ্ছে আপনার প্রত্যাশা ভেঙ্গে দিতে পারে।
জেরেমি তালিকা

@ জেরেমিলিস্ট যা বলেছেন তা স্পষ্ট is যে আমাকে কঠিন।
আদালত

36

রেলগুলি সম্প্রতি এটি অ্যাক্টিভেকর্ডে যুক্ত করেছে। এটি 5 টি কারাগারে মুক্তি পাবে বলে মনে হচ্ছে ইতোমধ্যে মাস্টার্ড করার প্রতিশ্রুতিবদ্ধ:

https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89

Post.where(column: 'something').or(Post.where(other: 'else'))

# => SELECT * FROM posts WHERE (column = 'something') OR (other = 'else)

23

5 রেলগুলি একটি orপদ্ধতি নিয়ে আসে । ( ডকুমেন্টেশনে এল কালি )

এই পদ্ধতিটি কোনও ActiveRecord::Relationবস্তুকে গ্রহণ করে । উদাহরণ:

User.where(first_name: 'James').or(User.where(last_name: 'Scott'))

14

আপনি যদি অ্যারেগুলি আর্গুমেন্ট হিসাবে ব্যবহার করতে চান তবে নিম্নলিখিত কোডটি রেল 4 এ কাজ করে:

query = Order.where(uuid: uuids, id: ids)
Order.where(query.where_values.map(&:to_sql).join(" OR "))
#=> Order Load (0.7ms)  SELECT "orders".* FROM "orders" WHERE ("orders"."uuid" IN ('5459eed8350e1b472bfee48375034103', '21313213jkads', '43ujrefdk2384us') OR "orders"."id" IN (2, 3, 4))

আরও তথ্য: অথবা রেল 4-এ আর্গুমেন্ট হিসাবে অ্যারে নিয়ে প্রশ্ন রয়েছে


9
বা এটি: Order.where(query.where_values.inject(:or))পুরোপুরি আরেল ব্যবহার করা।
ক্যামেরন মার্টিন

> বা কারাগুলিতে অ্যারে যুক্তি হিসাবে প্রশ্নগুলি 4. কার্যকর লিঙ্ক! ধন্যবাদ!
জেকেকে দ্রুত

7

MetaWhere প্লাগইন সম্পূর্ণরূপে আশ্চর্যজনক।

সহজেই ওআর এর এবং এন্ডের মিশ্রিত করুন, যে কোনও সংস্থার শর্তে যোগদান করুন এবং এমনকি আউট জয়েনসও নির্দিষ্ট করুন!

Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}

6

শর্তে কেবল একটি ওআর যুক্ত করুন

Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])

4
এটি রেল 2 এর জন্য আরও বেশি বাক্য গঠন এবং এটিতে আমার কমপক্ষে স্কয়ার স্ট্রিংয়ের একটি অংশ লেখার প্রয়োজন।
pho3nixf1re

3

আমি কেবলমাত্র ক্লায়েন্টের কাজ থেকে এই প্লাগইনটি বের করেছি যা আপনাকে স্কোপগুলি .or.প্রাক্তন, একত্রিত করতে দেয় । Post.published.or.authored_by(current_user)। স্কুয়েল (মেটা অনুসন্ধানের নতুন বাস্তবায়ন) দুর্দান্ত, তবে আপনাকে বা স্কোপগুলিকে বাধা দেয় না, সুতরাং ক্যোয়ারী যুক্তি কিছুটা রিয়ন্ডান্ট পেতে পারে।


3

রেল + আরেল সহ, আরও স্পষ্ট উপায়:

# Table name: messages
#
# sender_id:    integer
# recipient_id: integer
# content:      text

class Message < ActiveRecord::Base
  scope :by_participant, ->(user_id) do
    left  = arel_table[:sender_id].eq(user_id)
    right = arel_table[:recipient_id].eq(user_id)

    where(Arel::Nodes::Or.new(left, right))
  end
end

উত্পাদন:

$ Message.by_participant(User.first.id).to_sql 
=> SELECT `messages`.* 
     FROM `messages` 
    WHERE `messages`.`sender_id` = 1 
       OR `messages`.`recipient_id` = 1

3

আপনি এটি যেমন করতে পারে:

Person.where("name = ? OR age = ?", 'Pearl', 24)

বা আরও মার্জিত, Rails_or রত্ন ইনস্টল করুন এবং এটি পছন্দ করুন:

Person.where(:name => 'Pearl').or(:age => 24)

-2

আমি এটি যুক্ত করতে চাই এটি একটি অ্যাক্টিভেকর্ডের একাধিক বৈশিষ্ট্য অনুসন্ধান করার সমাধান। থেকে

.where(A: param[:A], B: param[:B])

এ এবং বি অনুসন্ধান করবে


-4
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')

2
আপনার উত্তরে কিছু ব্যাখ্যা যুক্ত করুন

1
আমি বিশ্বাস করি যে ম্যাথিউ ক্রিয়াকলাপ_একটি_ রত্নকে উল্লেখ করছে যা এই সিনট্যাক্সটির জন্য সমর্থন যোগ করে।
ড্যানিবি

2
যদি সত্য হয়, ধন্যবাদ @ ড্যানিবি। উত্তরে অবশ্যই এর প্রসঙ্গটি ব্যাখ্যা করতে হবে।
সেবাস্তিয়ালসো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.