簡単な例:ユーザーがフォームにユーザー名を入力すると、アプリケーションのデータベースに保存する前にそのテキストのユーザー名を作成する必要があります。Ruby on Rails - データを保存する前に変更することはできますか?
このコードはどこに置かれますか?小文字にするにはどのようにデータにアクセスしますか?
ありがとうございました。
簡単な例:ユーザーがフォームにユーザー名を入力すると、アプリケーションのデータベースに保存する前にそのテキストのユーザー名を作成する必要があります。Ruby on Rails - データを保存する前に変更することはできますか?
このコードはどこに置かれますか?小文字にするにはどのようにデータにアクセスしますか?
ありがとうございました。
あなたは例えば、あなたのUserモデル、そのようなことでActiveRecordをコールバックのいずれかを使用できます。一般的なケースでは
before_save { |user| user.username = user.username.downcase }
、コントローラのアクション に委任する必要がありますフォーム上のボタンを提出する場所のparams [: user_name]を使用できます。あなたは SomeModel.update(params)またはcreate(params)を実行する前に小文字にすることができます。
コントローラアクションで実行できます。私はObserverモデルとbefore_save方法でこのアクションを実行を追加することをお勧め
class User < ActiveRecord::Base
def username=(val)
write_attribute(:username, val.downcase)
end
end
コントローラーとモデルを強く結合することの結果について考える必要があります。 2つのコントローラがこのモデルのインスタンスを作成する必要がある場合はどうなりますか?コンソールを使用してユーザーを作成すると、開発者はユーザー名がダウンしてしまうのを忘れてしまいますか?ユニットテストはどうですか?私はより良いアプローチは、effkayによって提案されたActiveRecordのコールバックを使用することだと思います。 –
はい私も彼をあきらめました。私の推論:一箇所にいる限り、私は本当に気にしません。それはOPの質問から複数の場所があるように実際には見えなかった。だから私はおそらく働くことができる最も単純なものに行った。また、あなたは常にモデルを持っているとは限りません。しかし、このシナリオでは、OPが1つを使用しているように見えます。 – Gishu
あなたは属性ライターを上書きする必要があります。そして、どのコントローラやアクションがそれを作成しているかに関係なく、ユーザ名を小文字にすることが保証され、オブザーバ内で何らかのアクションを実行する際に問題が発生すると、例外がスローされ、オブジェクトは保存されません。
編集:ご注意くださいできませんそのモデルに関連付けられてbefore_save内のModel.saveを行う、そうでなければ無限ループに終わる。あなたはupdate_attributesなどをする必要があります。あなたのUserモデル(モデル/ user.rb)で
:
、ActiveRecordのコールバックを利用する:
before_save do
self.username = self.username.downcase
end
私の場合、 – Neeraj
私はこのコードを使用してから私を停止するバグを見ながら過ごしました。私のデータベースは、属性を傍受し、保存する前にfalse
に変更しようとするたびにロールバックされていました。
このスレッドはこのタスクを達成するためのGoogleの最初の結果でしたが、返された全体をカバーしていなかったので私の答えは貢献していますfalse
問題。
コールバックのいずれかがfalse
を返すと、すべてがdbにロールバックされます。
私は、データベースまたは@offer.accepted = false
で受け入れられないように作成するオファーを設定しようとしていました。問題は、この行がメソッド全体をfalseに戻し、プロセス全体をロールバックさせることでした。
true
その後
コードで投げてそれを固定:
before_save {|offer| offer.accepted = false; true}
テイクアウト:あなたは彼らが成功したい場合はあなたのコールバックがfalse
を返すことができません。
出典:rails 3 : Do i need to give return true in a before_save callback for an object.save to work?
def username=(str)
super(str.downcase)
end
私はこのはるかに簡単と思いました。
ActiveRecordコールバックの詳細:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html – Zargony
あなたがそのようなフックをたくさん持っている場合や、属性に対して多くの操作が実行されている場合、それらのメソッドを作成して与えることもできますラムダの代わりにメソッド名。 属性を変更するように設計されたコールバックが多数ある場合は、そのプロセスを簡素化する[attribute-filters](http://rubydoc.info/gems/attribute-filters/1.2.2/)gemが表示される場合もあります。 – siefca