2017-07-05 14 views
0

私は、40以上の列に格納された、多くの変数を含む予算を追跡するWebページを持っています。時間が経つにつれて、これらの予算に調整が加えられますが、私は時間と年々の変化を追跡できる必要があります。自分のモデルにプライベートメソッドを追加して、:before_updateコールバックによってトリガーされた既存のレコードの複製を作成する必要がありました。しかし、それは動作していません。更新によって既存のレコードが変更され、元のレコードはまったく保持されません。Rails - 既存のレコードを保存し、コピーに更新を適用する方法?

モデル:

class Budget < ActiveRecord::Base 

    before_update :copy_budget 

    private 

    def copy_budget 
    @budget = Budget.find(params[:id]) 
    @budget.dup 
    @budget.save 
    end 
end 

私はまだ、レールを学んでいる(これはRailsの4である)と私は、これはこれを行うための最善の方法だったと思います。そうでない場合は、レコードがすでに存在する場合は更新するためにルーティングするのではなく、常に新しいレコードをポストするようにフォームを設定する方が良いでしょうか?

現在のform_for行は次のようになります。

<%= form_for(@budget) do |f| %>

すべてが起きていない重複を除いて、それが必要として動作します。私は何が欠けていますか? .dup関数が:idを複製している可能性はありますか?これは、MySQLデータベースの自動インクリメントによって割り当てられます。したがって、.dupがすべてをコピーしている場合、:id以外のすべてのデータを新しいレコードにコピーする方法はありますか?

ご意見ありがとうございます。

+0

[audited](https://github.com/collectiveidea/audited)や['paper_trail'](https://github.com/)のような変更を監査するために構築されたライブラリを使用することをお勧めします。例えば、 – engineersmnky

答えて

1

dupメソッドは、IDなしで新しいオブジェクトを返しますが、その場所では更新されません。 copy_budgetメソッドは既にBudgetのインスタンスメソッドであるため、モデルではparamsにアクセスできないため、これを行う必要はありません(また、できません)。idで予算を検索し、代わりに現在のインスタンス(自己)。だから、次はあなたのためcopy_budget方法を修正するだろう変更しましたが、あなたはまだそれはあなたはそれが動作するように期待しているように動作しますがデータベース

def copy_budget 
    copy_of_budget = self.dup 
    copy_of_budget.save 
end 

に保存されます直前に、すでに変更されたオブジェクトをコピーしています。ただし、現在のバージョンのバージョンにコピーをリンクしているわけではありません(Budget id = 1はBudget id = 2の古いバージョンです)。私はPaperTrailのような宝石を見てみることをお勧めします。(あなたのニーズに合わない場合は、他にもたくさんの人がいるでしょう)すでに多くの問題や特徴を考えています。レコードが変更されました。

+0

OPに 'Budget'モデルで定義された'#copy_budget'があることに触れているかもしれません。 'params'にはアクセスできず、' @ budget'は単に 'self'でもかまいません。また、現在のオブジェクトを 'dupingするという事実は'#changes'を示さないので、dupは 'id'やタイムスタンプを持たず、変更されたオブジェクトを反映します(私は信じます)。 – engineersmnky

+0

シンプルなライム、あなたの提案に合わせてcopy_budgetメソッドを変更しようとしましたが、私のモデルでは何も重複していません。既存のレコードには変更が適用されていますが、コピーは作成されません。 –

+0

あなたはどのバージョンのレールを持っていますか?レール5.1.2にテストアプリケーションを作成しただけで、レコードを更新しても毎回新しい予算が作成されています。私の答えで述べたように、idを除いて両方のレコードは同じですが、すでに変更が加えられているレコードをコピーしているので、古いバージョンをコピーするようにコードを更新する必要があります([changes] http:// api。rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes)があなたに役立つかもしれません。私はまだこれをやっているいくつかの宝石をチェックアウトすることをお勧めします –

関連する問題