Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@jun68ykt

rewhereによるwhere条件の上書き(Railsガイド写経)

More than 3 years have passed since last update.

 Railsガイド書写による小ネタが続いております。本日は、8.5 rewhere です。

Article(記事)モデルを作ります。

Railsガイドとは異なるカラムですが、author(投稿者)とlikes_count(いいねの数)
というカラムを作っておきます。

[ykt68@macbook testapp]$ rails g model article author likes_count:integer
Running via Spring preloader in process 74847
Expected string default value for '--jbuilder'; got true (boolean)
      invoke  active_record
      create    db/migrate/20170225110425_create_articles.rb
      create    app/models/article.rb
      invoke    test_unit
      create      test/models/article_test.rb
      create      test/fixtures/articles.yml
[ykt68@macbook testapp]$ rails db:migrate
== 20170225110425 CreateArticles: migrating ===================================
-- create_table(:articles)
   -> 0.0127s
== 20170225110425 CreateArticles: migrated (0.0128s) ==========================

rails console を立ち上げます。

[ykt68@macbook testapp]$ rails c
Running via Spring preloader in process 74971
Loading development environment (Rails 5.0.1)

100個のレコードを作成します。

likes_countには、1以上100以下の乱数を入れます。

irb(main):001:0> 100.times do |n|
irb(main):002:1*   Article.create author:sprintf('著者-%03d',n), likes_count:rand(0..100)
irb(main):003:1> end
   (0.2ms)  BEGIN
  SQL (0.5ms)  INSERT INTO `articles` (`author`, `likes_count`, `created_at`, `updated_at`) VALUES ('著者-000', 0, '2017-02-25 20:06:19', '2017-02-25 20:06:19')
   (0.6ms)  COMMIT
   (0.2ms)  BEGIN ・・・
・・・
  SQL (0.2ms)  INSERT INTO `articles` (`author`, `likes_count`, `created_at`, `updated_at`) VALUES ('著者-099', 48, '2017-02-25 20:06:20', '2017-02-25 20:06:20')
   (0.3ms)  COMMIT
=> 100

whereとrewhereを使ってみます。

likes_countが50のものを取得

irb(main):004:0> Article.where(likes_count: 50)
  Article Load (9.6ms)  SELECT `articles`.* FROM `articles` WHERE `articles`.`likes_count` = 50
=> #<ActiveRecord::Relation [#<Article id: 42, author: "著者-041", likes_count: 50, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 68, author: "著者-067", likes_count: 50, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 75, author: "著者-074", likes_count: 50, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">]>

で、クエリに rewhere(likes_count: 80)を付加してみると、

irb(main):005:0> Article.where(likes_count: 50).rewhere(likes_count: 80)
  Article Load (3.8ms)  SELECT `articles`.* FROM `articles` WHERE `articles`.`likes_count` = 80
=> #<ActiveRecord::Relation [#<Article id: 72, author: "著者-071", likes_count: 80, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">]>

なるほど。
articles.likes_count = 50が、articles.likes_count = 80
上書きされています。

では、次に、whereの条件を likes_count > 50 にして、

irb(main):006:0> Article.where('likes_count > 50')
  Article Load (11.4ms)  SELECT `articles`.* FROM `articles` WHERE (likes_count > 50)
=> #<ActiveRecord::Relation [#<Article id: 2, author: "著者-001", likes_count: 92, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 3, author: "著者-002", likes_count: 68, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 4, author: "著者-003", likes_count: 57, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 9, author: "著者-008", likes_count: 87, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 13, author: "著者-012", likes_count: 69, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 16, author: "著者-015", likes_count: 56, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 18, author: "著者-017", likes_count: 52, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 19, author: "著者-018", likes_count: 78, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 25, author: "著者-024", likes_count: 86, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, #<Article id: 26, author: "著者-025", likes_count: 98, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">, ...]>

としてから、
「きっと、likes_count > 50が、likes_count > 80になってくれるのだろう」
という想定のもと、rewhere('likes_count > 80')を付加して

irb(main):007:0> Article.where('likes_count > 50').rewhere('likes_count > 80')

としてみると、残念

NoMethodError: undefined method `keys' for "likes_count > 80":String
    from /Users/ykt68/.rbenv/versions/2.2.6/lib/ruby/gems/2.2.0/gems/activerecord-5.0.1/lib/active_record/relation/query_methods.rb:650:in `rewhere'
・・・

となりました。
エラーメッセージに、
「"likes_count > 80"は文字列で、keysメソッドが無いよ」
と怒られています。
それでは、rewhere('likes_count > 80') をrewhere(likes_count: 80)に戻してやれば、
WHERE句の中で、likes_count = 80 によって likes_count > 50 が上書きされるかと思きや、

irb(main):008:0> Article.where('likes_count > 50').rewhere(likes_count: 80)
  Article Load (7.2ms)  SELECT `articles`.* FROM `articles` WHERE (likes_count > 50) AND `articles`.`likes_count` = 80
=> #<ActiveRecord::Relation [#<Article id: 72, author: "著者-071", likes_count: 80, created_at: "2017-02-25 11:06:19", updated_at: "2017-02-25 11:06:19">]>
irb(main):009:0> 

と、エラーにはなりませんが、

WHERE (likes_count > 50) AND `articles`.`likes_count` = 80

というWHERE句が生成されています。
ムムッ(←川平慈英のモノマネをする博多華丸口調で)

そこで Rails APIで、rewhereを調べると、

This is short-hand for unscope(where: conditions.keys).where(conditions).

Note that unlike reorder, we're only unscoping the named conditions – not the entire where statement.

ということで、

only unscoping the named conditions – not the entire where statement.

だそうです。

が、全然ノープロですわ。
rewhere('likes_count > 80')でもいけちゃうrewhere欲しければ
自分で書けよって話だと思いますし、こちとら、ActiveRecord様のような
スゴイもの、タダで使わせてもらってる身空でございますしおすし。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?