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

　Railsガイド書写による小ネタが続いております。本日は、[8.5 rewhere](https://railsguides.jp/active_record_querying.html#rewhere) です。 

## Article（記事）モデルを作ります。

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

```shell-session
[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 を立ち上げます。

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

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

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

```ruby
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のものを取得

```ruby
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)`を付加してみると、

```ruby
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` にして、

```ruby
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')`を付加して

```ruby
irb(main):007:0> Article.where('likes_count > 50').rewhere('likes_count > 80')
```
としてみると、残念

```ruby
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`　が上書きされるかと思きや、

```ruby
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> 
```

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

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

というWHERE句が生成されています。
ムムッ<font color='#AAAAAA'>（←川平慈英のモノマネをする博多華丸口調で）</font>

そこで [Rails API](http://api.rubyonrails.org/)で、`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 – <b>not the entire where statement.</b>

だそうです。

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