শৃঙ্খলা নীল ব্যবহার করে না এমন কারাগারগুলি


359

রেল 3 স্টাইল ব্যবহার করে আমি এর বিপরীতে কীভাবে লিখব:

Foo.includes(:bar).where(:bars=>{:id=>nil})

আমি যেখানে আইডি শূন্য নয় তা সন্ধান করতে চাই। আমি চেষ্টা করেছিলাম:

Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql

কিন্তু এটি ফিরে আসে:

=> "SELECT     \"foos\".* FROM       \"foos\"  WHERE  (\"bars\".\"id\" = 1)"

এটি অবশ্যই আমার যা প্রয়োজন তা নয়, এবং এটি প্রায় আর্েলের বাগের মতো মনে হয়।


2
!niltrueরুবিতে মূল্যায়ন করে এবং আরেল একটি এসকিউএল কোয়েরিতে অনুবাদ trueকরে 1। সুতরাং উত্পন্ন উত্সাহটি আসলে আপনি যা চেয়েছিলেন তা হ'ল - এটি কোনও আর্ল বাগ ছিল না।
ইয়ুভাল

উত্তর:


510

রেল 3 এর সাথে এটি করার প্রচলিত উপায়:

Foo.includes(:bar).where("bars.id IS NOT NULL")

অ্যাক্টিভেকর্ড 4.0 এবং উপরের অংশগুলি এতে যুক্ত where.notকরতে পারে:

Foo.includes(:bar).where.not('bars.id' => nil)
Foo.includes(:bar).where.not(bars: { id: nil })

টেবিলগুলির মধ্যে স্কোপগুলি নিয়ে কাজ করার সময়, আমি উত্তোলন করতে পছন্দ mergeকরি যাতে আমি বিদ্যমান স্কোপগুলি আরও সহজে ব্যবহার করতে পারি।

Foo.includes(:bar).merge(Bar.where.not(id: nil))

এছাড়াও, যেহেতু includesসর্বদা একটি যোগদানের কৌশল চয়ন করে না, আপনার referencesএখানেও ব্যবহার করা উচিত অন্যথায় আপনি অবৈধ এসকিউএল দিয়ে শেষ করতে পারেন।

Foo.includes(:bar)
   .references(:bar)
   .merge(Bar.where.not(id: nil))

1
এখানে সর্বশেষটি আমার জন্য কাজ করছে না, এর জন্য আমাদের কী কোনও অতিরিক্ত রত্ন বা প্লাগইন দরকার? আমি পেয়েছি: rails undefined method 'not_eq' for :confirmed_at:Symbol..
টিম বাশ

3
@ টিম হ্যাঁ, আমি উপরে উল্লিখিত মেটাওয়্যার রত্ন।
অ্যাডাম লাসেক

3
আমি এমন সমাধানটি পছন্দ করি যার জন্য অন্যান্য রত্নগুলির প্রয়োজন হয় না :) এটি কিছুটা কুৎসিত
হলেও

1
@ ইউরোশকে মেটাওয়েথ / স্কোয়েল ভাল মূল্যবান, এটি কেবল একটি ছোট্ট দিক। তবে অবশ্যই একটি সাধারণ মামলা জেনে রাখা ভাল know
অ্যাডাম লাসেক

1
@BKSpurgeon চেইনিং whereঅবস্থার কেবল একটি এবং AST নির্মাণ করছে এটা ডাটাবেসের আঘাত না যতক্ষণ না আপনি ভালো একটি টার্মিনাল পদ্ধতি আঘাত eachবা to_a। ক্যোয়ারী তৈরি করা কোনও পারফরম্যান্সের উদ্বেগ নয়; আপনি ডাটাবেস থেকে যা অনুরোধ করছেন তা হ'ল।
অ্যাডাম লাসেক

251

এটি আর্লে কোনও বাগ নয়, এটি আপনার যুক্তিতে একটি বাগ।

আপনি এখানে যা চান তা হ'ল:

Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))

2
আমি আগ্রহী যে যুক্তিটি তখন "1" তে পরিণত করার জন্য কী
শুডেসুনি

12
অনুমান হিসাবে, শূন্য ফিরে আসে true, যা একটি বুলিয়ান। :id => trueআপনাকে id = 1এসকিউএলিসে পেয়ে যায়।
জেটেটিক

কাঁচা এসকিএল টুকরো লেখা এড়াতে এটি একটি ভাল উপায়। সিনট্যাক্সটি যদিও স্কেলের মতো সংক্ষিপ্ত নয়।
কেলভিন

1
আমি স্ক্লাইট 3 দিয়ে এটি পরিচালনা করতে পারি না। sqlite3 দেখতে চায় field_name != 'NULL'
mjnissim

@ জেটিটিক আপনি পোস্টগ্র্রেস ব্যবহার না করা হলে, আপনি যে ক্ষেত্রে পাবেন id = 't':)
thekingoftruth

36

রেলস 4 এর জন্য:

সুতরাং, আপনি যা চাচ্ছেন তা হ'ল অভ্যন্তরীণ যোগদান, যাতে আপনার সত্যিকারের প্রিন্টে যোগ দেওয়া উচিত:

  Foo.joins(:bar)

  Select * from Foo Inner Join Bars ...

তবে, রেকর্ডটির জন্য, যদি আপনি "নট নুল" শর্তটি চান তবে কেবল প্রাকটিকেটটি ব্যবহার করুন:

Foo.includes(:bar).where.not(bars: {id: nil})

Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL

নোট করুন যে এই সিনট্যাক্সটি অবমূল্যায়নের রিপোর্ট করেছে (এটি একটি স্ট্রিং এসকিউএল স্নিপেটের কথা বলে, তবে আমি অনুমান করি যে হ্যাশের শর্তটি পার্সারে স্ট্রিংয়ে পরিবর্তিত হয়েছে?), সুতরাং শেষগুলি উল্লেখগুলি যুক্ত করার বিষয়ে নিশ্চিত হন:

Foo.includes(:bar).where.not(bars: {id: nil}).references(:bar)

প্রসারণ সতর্কতা: দেখে মনে হচ্ছে আপনি আগ্রহী লোডিং টেবিল (গুলি) (এর মধ্যে একটি: ....) যা স্ট্রিং এসকিউএল স্নিপেটে রেফারেন্স করা হয়েছে। উদাহরণ স্বরূপ:

Post.includes(:comments).where("comments.title = 'foo'")

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

Post.includes(:comments).where("comments.title = 'foo'").references(:comments)

1
referencesকল আমাকে সাহায্য!
theblang


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