0

分離された多数のエンジンを実装するRailsプロジェクトがあります。

  1. プライマリエンジン(常にそこにあります)
  2. 拡張エンジン#1(プライマリエンジンを拡張するオプションのプラグイン)
  3. 拡張エンジン#2(プライマリエンジンを拡張するオプションのプラグイン)
  4. 等。

ロングストーリー-ショート、プライマリエンジンのモデルに関係のあるモデルを追加するには、拡張エンジンが必要です。

拡張機能は他のエンジンの物理テーブルを変更すべきではありませんが、拡張機能がプライマリエンジンのテーブルを参照するための結合テーブルとして機能する独自のテーブルを作成できなかった理由はありません。

簡単にするために、以下に私がやろうとしていることを示します。

プライマリエンジン

... / app / models / models / user.rb

module PrimaryEngine
    User < ActiveRecord::Base
    End
end

車両エンジン

# .../vendor/engines/vehicle_engine/app/models/vehicle.rb
module VehicleEngine
    Vehicle < ActiveRecord::Base
    End
end

# .../vendor/engines/vehicle_engine/config/initializers/user_extension.rb
...
PrimaryEngine::User.class_eval do 
    has_one :vehicle, :through => :vehicle_engine_users_vehicles
end
...

結合テーブルを使用する必要がある唯一の理由は、プライマリエンジンの primary_engine_userテーブルを変更できない(すべきではない)ためです。primary_engine_user通常、テーブルに新しい列を追加するだけですprimary_engine_user.vehicle_id

:through =>重要なのは、その結合テーブルには機能を公開する必要があるものが何もないため、パーツのモデルを作成する必要がないということです。

CREATE TABLE vehicle_engine_users_vehicles
(
  primary_engine_user_id integer NOT NULL,
  vehicle_id integer NOT NULL
)

結合テーブルが推測されますが、指定する必要がない、のhas_oneように機能する方法があるかどうか疑問に思っています。has_and_belongs_to_many

ありがとう!

明確化の更新:

APrimaryEngine::Userは1台の車両を持つことがVehicleEngine::Vehicleできますが、多くの異なるユーザーを持つことができます。

4

2 に答える 2

1

したがって、あなたが求めているのは、スルーが推論されることではなく(has_and_belongs_to_manyがスルーを推論するため)、モデルなしでリンクテーブルを使用することです。

私はそうは思わない。:through オプションを使用すると、ActiveRecord は :through で指定されたアソシエーションに移動し、そのアソシエーションのモデルに移動します (したがって、スルー アソシエーションとスルー モデルの両方が存在する必要があります)。

先に進み、空のモデルを作成します。たいした問題にはなりません。

于 2013-02-25T18:34:24.543 に答える
0

has_one を has_and_belongs_to_many のように機能させる方法があるかどうか疑問に思っています。この場合、結合テーブルは推測されますが、指定する必要はありません。

1 対 1 の関係がある場合は、結合テーブルが必要ない場合があります。これは、いずれかのテーブルに外部キーを配置するだけで実行できるためです。しかし、あなたは外部キーを実行できないと言いました。

後で 1 対多または多対多に切り替える必要があることがわかっている場合は、id 列を持つ本格的な結合モデルを使用する可能性があります。(一般的なルールは、HABTM は 2 つの列 (結合するテーブルへの 2 つの外部キー) しか持たない結合テーブル用であり、それ以外の場合、結合テーブルはモデルになり、そのモデルを通じて has_many を実行できます。必要に応じて)これは@Marlin_Pierceが言ったことです。

has_one を単一の HABTM のように動作させるには、デフォルトの動作をオーバーライドすることになり、他のユーザーを混乱させることになります。やらないでください。

したがって、モデルにメソッドを追加して、has_one のように動作させることをお勧めします。

has_and_belongs_to_many :vehicles

def vehicle
  vehicles.first
end

def vehicle=(vehicle)
  vehicles = vehicle ? [vehicle] : []
end

HABTM と has_many は、行が返されなくてもリレーションシップが有効であれば常に空の配列を返すためtry、getter で a または nil をチェックする必要はありません。

しかし、これについてもっと考えてみると、本当にあなたが望んでいるのはhas_one :vehicle, through: :vehicle_engine_users_vehicle. これには結合モデルが必要ですが、これはあなたがやろうとしていることを実行するための「レールの方法」であり、こちらのガイドで説明されています。次に、これを行うための gem を作成している場合は、必要に応じて簡単にするために、結合モデルと関連する移行を作成するジェネレーターを作成できます。

于 2013-02-25T18:45:18.840 に答える