2

テーブル名は動的であり、モデル (タスク) の属性 (survey_id) に依存するため、関連付けられたモデル (limesurvey) のテーブル名を設定する必要があります。

私の現在の実装では、タスクが初期化されるときにテーブル名を設定します。

class task < ActiveRecord::Base
  after_initialize :setTablename
  has_one :limesurvey

  def setTablename
    Limesurvey.table_name = "lime_survey_#{self.survey_id}"
  end
end

この実装は機能しますが、setTablename-method は必要ではありませんが、すべてのタスクで呼び出されるという欠点があります。

関連付けlimsurveyがロードされる前にのみsetTablenameを実行するにはどうすればよいですか?

4

2 に答える 2

2

警告:コメント者が言及したように、あなたがトラブルの海に乗っていることに同意します. さらに、以前は少なくとも setTablename がすべてのタスクに対して呼び出されていたため、これはさらに悪化する可能性があります。

class Task < ActiveRecord::Base
  has_one :limesurvey

  def lime_survey
    @table_name || = (Limesurvey.table_name = "lime_survey_#{self.survey_id}")

    limesurvey
  end
end

これは、アンダースコアを使用してlimesurvey のバージョンを定義しますが、最初にテーブル名が設定されているかどうかを確認します。limsurvey の代わりにlime_survey を呼び出すと、求めていた効果が得られます。

Andy によって提案されたアプローチに似ています。ただし、関連付けは単なるメソッドですが、親クラス (またはモジュール) のメソッドではないため、関連付けを再定義して super を呼び出すことができるかどうかはわかりません。

于 2013-01-14T20:38:39.347 に答える
0

アソシエーションは、モデルに含まれるモジュールで定義された単なるメソッドであるため、他のメソッドと同じようにオーバーライドできます

class Task < ActiveRecord::Base
  has_one :limesurvey

  def limesurvey
    # do something here...

    super
  end
end

ただし、質問に対するコメントで人々が言及しているように、あなたがしていることは本当に悪い考えです。一度に 2 つのタスクが利用可能で、limesurvey両方の にアクセスしようとするとどうなりますか?

t1 = Task.first
t2 = Task.last

l1 = t1.limesurvey
l2 = t2.limesurvey

l1.update_attributes(foo: "bar")
# Oops... saves into the wrong table...

アプリ全体でこれを明示的に行うことをなんとか回避できたとしても、2 つの同時リクエストがある場合、偶発的に発生する可能性があります。

于 2013-01-14T20:26:39.390 に答える