0

私はRailsに比較的慣れていないので、問題を解決する方法が正しいかどうかはわかりませんが、いくつか問題があります

私の PC には MySQL がインストールされていますが、Heroku は PostgreSQL を使用しているため、特定の問題で両方の DBMS で動作するソリューションを設計しています。

私は次のコードを持っています:

begin
   @products_with_valid_offers = Product.joins(:variants).active.discount_valid.discount_date_valid_mySQL

   rescue ActiveRecord::StatementInvalid
      @products_with_valid_offers = Product.joins(:variants).active.discount_valid.discount_date_valid_postgreSQL
end

スコープは次のとおりです。

scope :active,  includes([:assets, :store]).where(:active => true, :deleted_at => nil, :stores => { :deleted_at => nil, :active => true }).order("products.created_at DESC")
scope :discount_date_valid_mySQL, where('DATE_FORMAT(NOW(),"%Y-%m-%d 23:59:59") + '" BETWEEN discount_from AND discount_to')
scope :discount_date_valid_postgreSQL, where('now()::date BETWEEN discount_from AND discount_to')

ご覧のとおり、日付形式を管理するには、DBMS ごとに 1 つずつ、2 つの異なるフォームが必要です。問題は、フローが例外に入らないことです。@products_with_valid_offers が MySQL の SQL エラーの場合、レスキュー ブロックに入って PostgreSQL 行を実行することはなく、エラーが返されます。

助けてください。:D

4

1 に答える 1

0

あなたの引用は でめちゃくちゃdiscount_date_valid_mySQLです。あなたはこう言いたいです:

scope :discount_date_valid_mySQL, where("DATE_FORMAT(NOW(),'%Y-%m-%d 23:59:59') BETWEEN discount_from AND discount_to")

これは少なくとも有効な Ruby コードです。

とはいえ、あなたの現在のアプローチはさまざまな点で悪いです:

  • 本番環境で常に例外があることを確認しています。
  • あるデータベース上で開発しているのに、別のデータベース上に展開している場合、これだけであらゆる種類の問題が発生します。
  • date_format(now(), '%Y-%m-%d')MySQL バージョンでのみ使用する必要があります。

他にも問題がある可能性がありますが、コードを分解するのにこれ以上時間を費やす必要はありません。より良い方法があります。MySQL と PostgreSQL (および SQLite も) の両方がサポートcurrent_dateされているため、1 つのものを両方に使用できます。

scope :discount_date_valid, where('current_date between discount_from and discount_to')

もちろん、すべてを UTC と見なしたいと仮定します。他のタイムゾーンを使用する場合は、次のようにします。

  1. anddiscount_fromdiscount_to日付列として保存します。日付には SQL のタイムゾーンがありません。おそらくすでにこれを行っていると思いますが、確認したいだけです。
  2. スコープを調整して、クライアント コードから現在の日付を取得します (適切なタイムゾーンを使用するように構成されていると思われます)。

    def self.discount_date_valid
        where(':current_date between discount_from and discount_to', :current_date => Date.today)
    end
    

スコープが適切なタイミングで評価されるようにするには、スコープにクラス メソッドを使用する必要がありますDate.today(つまり、クラスがロードされるときではなく、スコープが使用されるとき)。

また、PostgreSQL 上にデプロイする場合は、PostgreSQL 上で開発する必要があります。同じバージョンの PostgreSQL で開発およびデプロイしていることも確認する必要があります。あるスタック上で開発し、別のスタックにデプロイすると、あらゆる種類の無意味なフラストレーションと混乱が生じます。

于 2012-08-22T03:24:50.197 に答える