Rails多态关系

时间:2016-10-19 07:36:43

标签: ruby-on-rails ruby orm ruby-on-rails-5

我正在尝试使用rails 5的多态关系。

我很难弄清楚如何完成我的关系。

我有用户,可以预订酒店,餐馆等。

我的目的是通过API调用/ users / {id}时获取酒店名称和预订。

这是我的用户模型:

class User < ApplicationRecord
     has_many :reservations, as: :reservable
     has_many :hotels, through: :reservations
end

我的酒店型号:

class Hotel < ApplicationRecord
      has_many :reservations, as: :reservable
      belongs_to :users, through: :reservations
end

我的预订模式:

class Reservation < ApplicationRecord
      belongs_to :reservable, polymorphic: true
      belongs_to :users
      belongs_to :hotels
end

迁移:

用户:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :first_name
      t.string :last_name
      t.string :email

      t.timestamps
    end
  end
end

预订:

class CreateReservations < ActiveRecord::Migration[5.0]
  def change
    create_table :reservations do |t|
      t.belongs_to :hotel, index: true
      t.belongs_to :user, index: true
      t.datetime :date_from
      t.datetime :date_to

      t.timestamps
    end
  end
end
class ReservationPolymorphism < ActiveRecord::Migration[5.0]
  def change
      rename_column :reservations, :hotel_id, :reservable_id
      change_column :reservations, :reservable_id, polymorphic: true
      add_column :reservations, :reservable_type, :string
  end
end

酒店:

class CreateHotels < ActiveRecord::Migration[5.0]
  def change
    create_table :hotels do |t|
      t.string :name
      t.string :address
      t.string :postal_code
      t.string :town

      t.timestamps
    end
  end
end

我的预订表中只有一行:

mysql> select * from reservations;
+----+---------------+-----------------+---------+---------------------+---------------------+---------------------+---------------------+
| id | reservable_id | reservable_type | user_id | date_from           | date_to             | created_at          | updated_at          |
+----+---------------+-----------------+---------+---------------------+---------------------+---------------------+---------------------+
|  1 |             1 | Hotel           |       1 | 2017-01-12 00:00:00 | 2017-01-15 00:00:00 | 2016-10-19 09:18:01 | 2016-10-19 09:18:01 |
+----+---------------+-----------------+---------+---------------------+---------------------+---------------------+---------------------+

使用API​​时没有结果。

以下是我使用Rails控制台获得的内容:

2.2.3 :001 > thomas = User.find(1)
  User Load (0.2ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, first_name: "Thomas", last_name: "Dupont", email: "thomas.dupont@yopmail.com", created_at: "2016-10-18 21:12:12", updated_at: "2016-10-18 21:12:12"> 
2.2.3 :003 >   thomas.reservations
  Reservation Load (0.3ms)  SELECT `reservations`.* FROM `reservations` WHERE `reservations`.`reservable_id` = 1 AND `reservations`.`reservable_type` = 'User'
2.2.3 :005 > thomas.hotels
NameError: uninitialized constant User::Hotels

所以我可以看到我在rails关系和多态性方面犯了一些基本错误,但我真的找不到我错在哪里。

我想我犯了一个错误。 我假设多态可以用于加载其他模型及其表(如“morpho”和“eloquent / laravel”),而只是加载一个没有数据表示的模型(如本文所述:https://robots.thoughtbot.com/using-polymorphism-to-make-a-better-activity-feed-in-rails)< / p>

2 个答案:

答案 0 :(得分:0)

我想在查看代码时,您已经在多态关联之上编写了额外的关联,

要创建多态关联,只需以下代码即可。无需在模型中传递额外的关联。请按如下方式重构您的代码, 用户模型

for(var i=0; i<3; i++){
    document.write("<div class='checkbox'><label><input type='checkbox' value='1' onclick='changeText();' >Item</label></div><input type='text' name='myItem' value='0' disabled/><br/>");
}

var item_box = document.getElementsByName('myItem');
var x;
//alert(item_box.length);
function changeText(){
  for(x=0;x<item_box.length;x++){
   if(item_box[x].hasAttribute('checked')){
    item_box[x].value="0";
    item_box[x].setAttribute('checked', true);
    item_box[x].removeAttribute('checked');
    item_box[x].setAttribute('disabled', false);
   } else {
    item_box[x].value="1";
    item_box[x].setAttribute('checked', false);
    item_box[x].setAttribute('disabled', true);
    item_box[x].removeAttribute('disabled');
   }
  }
}

酒店模特:

class User < ApplicationRecord
     has_many :reservations, as: :reservable
end

预订模式:

class Hotel < ApplicationRecord
      has_many :reservations, as: :reservable
end

在预订的迁移文件中,添加可预留的

class Reservation < ApplicationRecord
      belongs_to :reservable, polymorphic: true
end

答案 1 :(得分:0)

好的,我把它整理出来了:

这是预订模式:

class Reservation < ApplicationRecord
      belongs_to :reservable, polymorphic: true
end

这是酒店模特:

class Hotel < ApplicationRecord
end

用户模型:

class User < ApplicationRecord
     has_many :reservations
end

我是如何在rails console中获得结果的:

Running via Spring preloader in process 87452
Loading development environment (Rails 5.0.0.1)
2.2.3 :001 > u = User.find(1)
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, first_name: "Thomas", last_name: "Dupont", email: "thomas.dupont@yopmail.com", created_at: "2016-10-18 21:12:12", updated_at: "2016-10-18 21:12:12"> 
2.2.3 :002 > u.reservations
  Reservation Load (0.3ms)  SELECT `reservations`.* FROM `reservations` WHERE `reservations`.`user_id` = 1
 => #<ActiveRecord::Associations::CollectionProxy [#<Reservation id: 1, reservable_id: 1, reservable_type: "Hotel", user_id: 1, date_from: "2017-01-12 00:00:00", date_to: "2017-01-15 00:00:00", created_at: "2016-10-19 09:18:01", updated_at: "2016-10-19 09:18:01">]> 
2.2.3 :003 > u.reservations.first.reservable
  Hotel Load (0.3ms)  SELECT  `hotels`.* FROM `hotels` WHERE `hotels`.`id` = 1 LIMIT 1
 => #<Hotel id: 1, name: "HYATT REGENCY HOTEL", address: "3 Place du Général Kœnig", postal_code: "75017", town: "PARIS", created_at: "2016-10-19 08:36:55", updated_at: "2016-10-19 08:36:55">