1

RoR プロジェクトに取り組んでおり、列の日時を更新しようとしています。私が作成した列は「deleted_at」と呼ばれ、コントローラーのコードは次のとおりです。

def destroy
    p DateTime.now
    p Time.now.to_formatted_s(:db)
    domain = Domain.find(params[:id])
    p "RECORD: " + domain.domain.to_s
    domain.update(deleted_at: Time.now.to_formatted_s(:db))

    respond_to do |format|
        format.html { redirect_to @domain, notice: 'Domain was successfully deleted' }
        format.js { render action: "destroy" }
    end
end

ドメイン名などの別の列を更新しようとしても、問題なく更新できます。そうしないと、deleted_at 列を更新できません。私はさまざまな方法で試しましたが、何も得られません。

これは、destroy メソッドが実行されたときの Rails コンソールからのログです。

Started DELETE "/domains/28" for 10.0.2.2 at 2013-09-06 12:56:35 +0000
Processing by DomainsController#destroy as JS
  Parameters: {"id"=>"28"}
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 13 ORDER BY `users`.`id` ASC LIMIT 1
Fri, 06 Sep 2013 12:56:36 +0000
"2013-09-06 12:56:36"
  Domain Load (0.3ms)  SELECT `domains`.* FROM `domains` WHERE `domains`.`id` = 28 LIMIT 1
"RECORD: www.example.com"
   (0.3ms)  BEGIN
  Domain Load (0.6ms)  SELECT `domains`.* FROM `domains` WHERE `domains`.`domain` = 'www.example.com' AND `domains`.`user_id` = 13 LIMIT 1
   (0.4ms)  ROLLBACK
  Rendered domains/destroy.js.erb (0.1ms)
Completed 200 OK in 104ms (Views: 90.0ms | ActiveRecord: 2.0ms)

ご覧のとおり、日時の形式は正しく、適切に出力されていますが、update メソッドは実際には UPDATE ではなく SELECT を実行しています。

どうしたの?

ありがとう。

編集-------------------

みんなのおかげで、私は問題を見つけました(まだ解決策ではありません)。それは検証規則でした。エラーを印刷したところ、次のようになりました。

ERROR: You already have this domain in use.

このメッセージは (domain.rb) によって生成されます:

class Domain < ActiveRecord::Base

    validate :domainIsUnique?

    private

    def domainIsUnique?

        if Domain.find_by domain: domain, user_id: user_id
            # Domain and user_id found, throwing error
            errors.add(:domain, "You already have this domain in use.")
        end
    end
end

そのため、この検証は常にプロセスを台無しにしているため、何も更新できません。私が理解していないのは、追加ではなく更新しているだけの場合、この検証が自分自身を上げているのはなぜですか...

4

4 に答える 4

1

Doonは正しい方向に進んでいると思います...更新時に常に存在する特定のドメインとユーザーのレコードがあるかどうかを検索しているだけなので、何かを更新しようとすると検証は失敗します。更新自体があなたの条件を満たしています...

ユーザーを対象とした一意性検証を追加する Doon のソリューションを受け入れるか、作成時にのみ検証を実行することができます。例えば

validate :domain_is_unique?, on: :create

おっと、ドメインを更新すると、それに関する編集が機能するのを見ました...検証がユーザーとドメインをチェックしているため、それが機能することが期待されます。これらのいずれかを変更すると、「ダーティ」レコードは検証クエリと一致しなくなります。

明確にするために、ユーザーまたはドメインのいずれかを更新できますが、クエリがドメインとユーザーの現在のオブジェクトと一致するため、他の更新では検証が失敗します。

于 2013-09-07T15:05:09.290 に答える
0

編集

これはうまくいくはずです

domain.update(deleted_at: Time.now.utc)

手動セットに分割してから保存してみてください。Update は、結果がデータベースに保存されたかどうかに関係なく、クラスを返します。

domain.deleted_at = Time.now
raise "Error saving!" unless domain.save

ドキュメントを参照してください。

検証に合格した場合、オブジェクト (または複数のオブジェクト) を更新してデータベースに保存します。オブジェクトがデータベースに正常に保存されたかどうかに関係なく、結果のオブジェクトが返されます。

于 2013-09-06T13:07:07.667 に答える
0

以下を使用して列を更新してみてください。

def destroy
  domain = Domain.find(params[:id])
  domain.update_attributes(deleted_at: Time.now.utc) # or Time.now
  respond_to do |format|
    format.html { redirect_to @domain, notice: 'Domain was successfully deleted' }
    format.js { render action: "destroy" }
  end
end
于 2013-09-06T13:53:45.673 に答える