简体   繁体   English

Rails和多态关联

[英]Rails and polymorphic associations

I have three models: User , Company , and Subscription . 我有三种模型: UserCompanySubscription What I am trying to accomplish is a Subscription belongs to either a User OR a Company . 我要完成的工作是Subscription属于User还是Company

To try accomplish this, I referenced this guide , but I have been unsuccessful as the record creation keeps rolling back. 为了尝试实现此目的,我参考了本指南 ,但是由于记录的创建一直在回滚,因此我一直没有成功。

here's my Company model: 这是我的Company模型:

# app/models/company.rb
class Company < ApplicationRecord
    has_many :subscriptions, dependent: :destroy, as: :imageable
end

here's my User model: 这是我的User模型:

# app/models/user.rb
class User < ApplicationRecord
  has_many :subscriptions, dependent: :destroy, as: :imageable
end

and finally, here's my Subscription model: 最后,这是我的Subscription模型:

class Subscription < ApplicationRecord
    belongs_to :imageable, polymorphic: true
end

Now as far as the migration file, this is my Subscription migration file: 现在,就迁移文件而言,这是我的Subscription迁移文件:

class CreateSubscriptions < ActiveRecord::Migration[5.1]
  def change
    create_table :subscriptions do |t|
      t.references :imageable, polymorphic: true, index: true
      t.date :start_date
      t.date :stop_date

      t.timestamps
    end
  end
end

As far as what I can see, this is pretty much exactly like the guide shows, but it keeps rolling back. 据我所见,这几乎完全与指南中显示的一样,但是它一直在回滚。 Here's the output of the rails console: 这是rails控制台的输出:

Loading development environment (Rails 5.1.6)
2.5.1 :001 > Subscription.create(imageable_id: 1, start_date: Time.now, stop_date: 2.days.from_now)
   (8.6ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
   (0.2ms)  BEGIN
   (0.3ms)  ROLLBACK
 => #<Subscription id: nil, imageable_type: nil, imageable_id: 1, start_date: "2018-10-10", stop_date: "2018-10-12", created_at: nil, updated_at: nil> 
2.5.1 :002 > 

Here are the questions that I have: 这是我的问题:

  1. Why is there an imageable_type field? 为什么会有imageable_type字段? Is that created by t.references and if so, do I need this? 它是由t.references创建的,如果是的话,我需要吗? Can I just use imageable_id instead of t.references as the other part of the suggestion shows? 我可以只使用imageable_id代替t.references作为的建议显示,另一部分?
  2. Why is it rolling back? 为什么会回滚? Are polymorphic associations done differently in Rails 5.x or something by chance? 在Rails 5.x中,多态关联是否有所不同?还是偶然?
  3. According to the graph shown in the guide, it looks like if a picture belongs to imageable_id 4, then if there is an employee AND a production with the ID of 4, then a picture would belongs to both instead of one or the other like I'm trying to accomplish. 根据指南中显示的图表,看起来如果一张图片属于imageable_id 4,那么如果有一个员工AND一部ID为4的作品,那么一张图片将属于两者,而不是像我一样正在努力实现。 Correct? 正确?

For polymorphic association, you should also pass imageable_type along with imageable_id . 对于多态关联,还应该将imageable_typeimageable_id一起传递。 You don't do it and that's why it doesn't work, most probably (ie there might be other reasons, I don't know, but this one is pretty obvious). 您不这样做,这就是为什么它不起作用的原因(很可能是这样(即,可能还有其他原因,我不知道,但这很明显))。

imageable_type holds the name of the class of the record given Subscription is associated to. imageable_type保存与订阅相关联的记录的类的名称。

In your association, Imageable type will contain the class name and imageble id will contain the id of that class. 在您的关联中,可成像类型将包含类名称,可成像ID将包含该类的ID。 So if you want to create subscription for user you can do like below 因此,如果您要为用户创建订阅,可以按照以下步骤进行操作

User.first.subcriptions.create(start_date: Time.now, stop_date: 2.days.from_now)

So it will automatically pick up First user's id in imageable id and take "User" as imageable type. 因此,它将自动在可成像ID中选取第一个用户的ID,并将“用户”作为可成像类型。

If you want to create subscription manually, you must have to pass both fields imageable type and imageble id like below, 如果您想手动创建订阅,则必须同时传递可成像类型和可成像ID字段,如下所示,

Subscription.create(imageable_id: 1, imageable_type: "User", start_date: Time.now, stop_date: 2.days.from_now)
  1. Why is there an imageable_type field? 为什么会有imageable_type字段? Is that created by t.references and if so, do I need this? 它是由t.references创建的,如果是的话,我需要吗? Can I just use imageable_id instead of t.references as the other part of the suggestion shows? 如建议的其他部分所示,我可以只使用imageable_id代替t.references吗?

=> imageable_type will contain the class of associate model like "User" or "Company" => imageable_type将包含关联模型的类别,例如“用户”或“公司”

  1. Why is it rolling back? 为什么会回滚? Are polymorphic associations done differently in Rails 5.x or something by chance? 在Rails 5.x中,多态关联是否有所不同?还是偶然?

=> No, you setup it correctly =>否,您已正确设置

  1. According to the graph shown in the guide, it looks like if a picture belongs to imageable_id 4, then if there is an employee AND a production with the ID of 4, then a picture would belongs to both instead of one or the other like I'm trying to accomplish. 根据指南中显示的图表,看起来如果一张图片属于imageable_id 4,那么如果有一个员工AND一部ID为4的作品,那么一张图片将属于两者,而不是像我一样正在努力实现。 Correct ? 对吗

=> It depends on both imageable_id and imageble_type , so by combination of both this you will get record. =>这取决于imageable_id和imageble_type,因此通过将两者结合使用,您将获得记录。 If imageable_id is 4 and imageable_type is "Picture" then it will take Picture with id 4. 如果imageable_id为4,而imageable_type为“图片”,则它将获取ID为4的图片。

Please check this link for understaing 请检查此链接是否足够

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM