1

Ruby on Rails 3.2.2 を使用していますが、インスタンスがデータベースに格納される前に、インスタンスの以前のステータスに基づいてチェックを実行したいと考えています。@articleつまり、関連するデータベースに既に保存されているデータを利用するメソッドを実行する必要があります@article(以下の場合、データはであり、 では{:id => 1, :title => "Sample title", :content => "Sample content", :status => "private"}ありません {:id => 1, :title => "Sample title changed!", :content => "Sample content", :status => "private"})。

属性値が変更された後、元のインスタンスを「取得」/「再構築」することを考えました。あれは:

# In the controller file

# @article.attributes
# => {:id => 1, :title => "Sample title", :content => "Sample content", :status => "private"}
@article.update_attributes(params[:article])
# => {:id => 1, :title => "Sample title changed!", :content => "Sample content", :status => "private"}


# In the model file
before_save :retrieve_original

def retrieve_original
  # self.attributes
  # => {:id => 1, :title => "Sample title changed!", :content => "Sample content", :status => "private"}

  original = ... # ?
  # original.id
  # => nil
  # original.attributes
  # => {:title => "Sample title", :content => "Sample content", :status => "private"}
  # self.attributes
  # => {:id => 1, :title => "Sample title changed!", :content => "Sample content", :status => "private"}
end

したがって、オブジェクトあり、インスタンスの単なる複製であるoriginal必要があります (属性が変更されていない場合とない場合)。Article@articleid@article

Ruby on Rails のメソッド (ActiveRecord::Base.dupや などActiveModel::Dirty.changed_attributes) を試してみましたが、解決策が見つかりませんでした。さらに、自分のやりたいことを実現するには、自分のアプローチよりも優れた方法があると思います。 もしそうなら、私は何をすればよいですか?


たとえば、記事が公開されている場合、タイトルの値を変更できないようにする必要があるためです。記事が非公開の場合、タイトルの値を変更できる必要があります。もちろん、編集した記事のデータを保存する前に、そのデータを更新しようとするすべての試行に対して、そのチェックを行う必要があります (これには、before_saveコールバックを使用することにしました)。ただし、ユーザーがタイトルの値とプライベートの値をパブリックに変更しようとすると、すべてのチェックがパブリックの「コンテキスト」で実行されますが、以前のステータスが非公開だったため、これらのチェックは引き続きプライベートの「コンテキスト」で実行されることを望みます.

4

3 に答える 3

3

フックで変更ハッシュを通過できるようです。つまり、変更されたバージョンのdup場合は、変更されたバージョンを調べて、属性をコピーの状態に戻します。clonechanges

于 2012-05-07T00:58:59.503 に答える
0

ただ保存する

@article = Article.find(params[:id])`
@orginal = @article
if @article.update_attributes(params[:article])
  @original.do_some_method_that_probably_should_be_a_before_update
  #.... whatever is next .....
end

または、自分がしなければならないと思うことを、なぜしなければならないのかを考え直してください。

于 2012-05-07T01:01:00.017 に答える
0

これを行うにはいくつかの方法があります。基本的に、後で変更を元に戻してからチェックするよりも、変更が行われる前にオブジェクトのコピーを作成する方が簡単です。

これを行う 1 つの方法は、次のように現在のオブジェクトの「属性」から新しいオブジェクトを作成することです。

tmp_article = @article.attributes

モデル オブジェクトに変更を加える前に、これを行ってください。次に、保存する前に.diff、レールに組み込まれているハッシュ メソッドを使用できます。

diff_hash = tmp_article - @article.attributes
# diff will now contain any differences. It will be empty if they are identical.

Rails の diff 拡張機能へのリンクは次のとおりです。

https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/diff.rb

于 2012-05-07T01:05:13.627 に答える