1

架空のレンタカー アプリケーションがあるとします。

ユーザー、車、住所があります。

user (id, name, email)
  has_many :addresses
  has_many :cars

car (id, name)
  belongs_to :user

address (id, name, user_id)
  belongs_to :user

各ユーザーは、複数の住所と車を持っています。住所は、ユーザーが自分の車を貸すことができる場所です。

さて、このモデルでは、次のことを行いたいと思います (ユーザー #1 が 2 つの住所と 3 台の車を持っているとします)。

Settings for User #1 : 
(specify at which address each of your cars are available)
/-------------------------------------------\
|           |  Car #1  | Car #2  |  Car #3  |
|-----------+----------+---------+----------|
| Address 1 |   yes    |  yes    |    no    |
|-----------+----------+---------+----------|
| Address 2 |   no     |  no     |   yes    |
\-------------------------------------------/

テーブルを作成できると思いますcars_addresses(id, car_id, address_id, available:bool)

しかし、アクティブレコードでそれを指定する方法がわかりません。だから私の質問は:

  • これは正しいスキーマ構造ですか?
  • アクティブなレコードを介してそれを実装するにはどうすればよいですか?
4

2 に答える 2

2

必要なのは、cars と address の間の has_and_belongs_to_many です。しかし、多くのラビイストは、この関係は決して使用すべきではないと言うでしょう (代わりに has_many :through を使用する必要があります)。これは、これらのモデル間で保存する必要がある追加情報を考えられないため、最適な場所です。したがって、次のようになります。

user (id, name, email)
  has_many :addresses
  has_many :cars

car (id, name)
  belongs_to :user
  has_and_belongs_to_many :addresses

address (id, name, user_id)
  belongs_to :user
  has_and_belongs_to_many :cars

次に、id なしで address_id と car_id の 2 つの列を持つテーブル addresses_cars (注文は重要、モデルは不要) を作成する必要があります。それでおしまい!それは「魔法のように」動作します:

user.cars.first.addresses => list of location car is available
user.addresses.first.cars => list of cars available under address
user.addresses.first.cars << user.cars.first => add a car to given address
于 2013-08-07T18:42:09.830 に答える
1

それはあなたの「車」モデルが何を表しているかによって異なります。

一度に複数の場所に配置できない物理的な車の場合は、別のリレーションを使用できます。

car (id, name, location_id)
    belongs_to :user
    belongs_to :location

location (id, name, user_id)
    belongs_to :user
    has_many :cars

これにより、関係が機能します。

#list each car and it's location
current_user.cars.each do |car| { puts "#{car.name} is at #{car.location.name}" }  

また

#how many cars are at each location
current_user.locations.each do |location| { puts "#{location.cars.count} of your cars are at #{location.name}" }

車の場所を設定するには:

#move car with id=5 to location with id=15
c=Car.find(5)
l=Location.find(15)
c.location=l
c.save

また

c=Car.find(5)
c.location_id=15
c.save

ところで、モデルに「住所」ではなく「場所」という名前を付けることをお勧めします。Ruby は、モデルの複数形名を持つ多くのメソッドを自動的に生成するため、単純な複数形の単語を使用すると、混乱を避けることができます。

于 2013-08-07T18:40:55.487 に答える