ラベル ActiveRecord の投稿を表示しています。 すべての投稿を表示
ラベル ActiveRecord の投稿を表示しています。 すべての投稿を表示

2015年3月3日火曜日

saveで ActiveRecord::ReadOnlyRecordの対処方法

RailsのActiveRecordでsaveしようとしたら、ActiveRecord::ReadOnlyRecordが発生しました。
私の原因として、joinsメソッドを使って取得したレコードに対して、saveしようとしたのがダメなようです。

発生事象

ダメ例を簡単に書くと下記のようになります。

user_items = UserItems.joins(:user)

user_items.each do |user_item|
  user_item.name = 'aaaaa'
  user_item.save ## ここでエラー
end

対処方法

対象方法としては、readonly(false) メソッドを呼び出します。

user_items = UserItems.joins(:user).readonly(false) ## <= 追加

user_items.each do |user_item|
  user_item.name = 'aaaaa'
  user_item.save
end

とやると、saveに成功します。

2014年11月25日火曜日

ActiveRecordのMigrationでAddColumnしたカラムに別カラムの値を代入する。

ActiveRecordのMigrationでAddColumnしたカラムに別カラムの値を代入する方法です。
結果直接、SQLを投げる結論に行き着きました。
def change
  add_column :users, :value2, :integer
  execute 'UPDATE users SET value2 = value1'
end
Usersテーブルにvalue2カラムを追加して、初期値として、value1の値をいれるようなケースを想定しています。

他の方法として、modelを使うパターンもあります。
class User < ActiveRecord::Base; end

def change
  add_column :users, :value2, :integer

  User.all.each do |user|
      user.value2 = user.value1
      user.save
  end
end

2014年11月13日木曜日

RailsのActive RecordでDISTINCTする方法

商品一覧の中から、重複を除いたブランドIDの一覧を取得したい場合、SQLのDISTINCTの代わりに、
Active Recordではuniqを使います

コード

@items = Item.select('bland_id').uniq

結果

結果として以下のような結果が返却されます
selectしているので、selectに指定したカラムにしかアクセスできません。
<Item bland_id: 3249>
<Item bland_id: 3250>
<Item bland_id: 1737>

使い方

ループでまわした場合は、以下のようにします。
@items.each do |item|
  p item.bland_id
end

2014年10月17日金曜日

ActiveRecordでhavingする方法

ActiveRecordでhavingを使いたい場合。
bookテーブルでカテゴリが同じものの、価格の合計が10000円以上のもの見たいな想定です。
Book.group('category').having('sum(price) >= 10000')
発行されるSQLは、以下のようになります。
SELECT
  book.*
FROM book
GROUP BY category
HAVING sum(price) > 10000

statistics