Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:自我引用关联让我头晕目眩_Ruby On Rails_Associations_Self Join - Fatal编程技术网

Ruby on rails Rails:自我引用关联让我头晕目眩

Ruby on rails Rails:自我引用关联让我头晕目眩,ruby-on-rails,associations,self-join,Ruby On Rails,Associations,Self Join,我目前正在从事一个利用RubyonRails的小型学校项目,我在让我的自引用关联正常工作方面遇到了一些问题 上下文 my web app的预期功能是让用户发布房屋/公寓,供其他用户搜索和租赁。因为我对特定的关联有问题,所以我使用的是一个完全精简的版本,它只有两个模型,用户和租赁 我正在努力实现的目标 理想情况下,当一个人首次在网站上注册时,会创建一个用户对象来保存他们的信息,如电子邮件和密码。然后,用户可以发布列表或搜索列表 一旦创建了一个帖子,并且另一个用户决定租用发布的房屋,就会创建一个租赁

我目前正在从事一个利用RubyonRails的小型学校项目,我在让我的自引用关联正常工作方面遇到了一些问题

上下文

my web app的预期功能是让用户发布房屋/公寓,供其他用户搜索和租赁。因为我对特定的关联有问题,所以我使用的是一个完全精简的版本,它只有两个模型,用户和租赁

我正在努力实现的目标

理想情况下,当一个人首次在网站上注册时,会创建一个用户对象来保存他们的信息,如电子邮件和密码。然后,用户可以发布列表或搜索列表

一旦创建了一个帖子,并且另一个用户决定租用发布的房屋,就会创建一个租赁对象,该对象包含发布用户的ID以及租赁用户的ID,分别别名为“房东ID”和“租户ID”

现在,应根据是否存在ID为房东或房客的租赁对象,将用户标识为用户、房东或房客(或房东和房客)。此标识将用于确定用户是否可以访问站点的其他区域

userFoo.leases
这将为我提供一个与用户ID关联的所有租赁对象的列表,无论它是作为房东还是租户

userFoo.tenants
这应该给我一个用户对象的列表,它的ID与通过租约作为租户的userFoo的ID相关联,如果我请求房东,则相反

代码

用户类

class User < ApplicationRecord
  has_many :tenants, class_name: "Lease", foreign_key: "landlord_id"
  has_many :landlords, class_name: "Lease", foreign_key: "tenant_id"
end
怎么了?

userFoo.leases
通常情况下,通过将用户ID作为“用户ID”与租约关联,用户将拥有多个租约。但是,由于我使用的是“租户ID”和“房东ID”,此命令失败,因为它无法在租约表中找到“用户ID”

userFoo.tenants
此命令为我提供了一个所有租赁对象的列表,其中userFoo的ID关联为“Lown_ID”,而不是所有与userFoo的ID关联为租户的用户对象。要按原样检索租户,我必须使用以下命令:

userFoo.tenants.first.tenant
结论 我很难理解这些更深、更复杂的关联,我花了一些时间试图找到一个详细的参考资料,其中包括了所有的论点,但我真正能找到的只是一些小博客文章,其中引用了guides.rubyonrails.com上的“员工”和“经理”示例。我认为一个问题是,我不确定我是否在表模式中正确反映了模型关联

如果有人能给我指出正确的方向,我非常乐意自学。我也愿意接受其他解决方案,但只有当我无法从这个设置中获得我想要的功能时,因为我的导师特别要求我这样做


提前感谢您的帮助!非常感谢。

根据您的要求,您可以这样尝试:

# app/models/user.rb

class User < ApplicationRecord
  has_many :owned_properties, class_name: "Property", foreign_key: "landlord_id"
  has_many :rented_properties, class_name: "Property", foreign_key: "tenant_id"
end
如果要获取用户所有的属性,请使用
user.owned\u properties

如果要获取用户的所有租用属性,请使用
user.rendered\u properties

^^在这两种情况下,您将获得
属性
类的对象

如果您想获得房产的房东,请使用
property.lown

如果要获取属性的租户,请使用
property.tenant

^^在这两种情况下,您将获得
User
类的对象

如果需要,您可以向属性表添加其他属性,如:
name
price


我想,这会对你有帮助。谢谢:)愉快的编码:)

这可能会帮助你,非常感谢你,Aleksandrus。第二个答案正是我想要的!这回答了你的问题吗?非常感谢你!我发现我犯的错误是,我试图在rails文档中应用单向所有权示例,其中Employee1可以属于Employee2,这使Employee2成为一个管理者,并使其在两个方向上都起作用。在我的应用程序中,用户不应该属于其他用户,因为实际上是财产以及拥有或租赁它的人定义了用户作为房东或承租人的角色。因此,即使我的代码有效,您的示例也能更准确地表示现实世界中的关联。再次感谢你的帮助!这还允许我添加“has_many:tenants,through::owned_properties”和与用户模型相反的内容,这样我就可以执行“userFoo.tenants”了,它可以工作了!
userFoo.leases
userFoo.tenants
userFoo.tenants.first.tenant
# app/models/user.rb

class User < ApplicationRecord
  has_many :owned_properties, class_name: "Property", foreign_key: "landlord_id"
  has_many :rented_properties, class_name: "Property", foreign_key: "tenant_id"
end
# app/models/property.rb

class Property < ApplicationRecord
  belongs_to :landlord, class_name: "User"
  belongs_to :tenant, class_name: "User"
end
# db/migrations/20201018054951_create_users.rb

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name,            null: false
      t.string :email,           null: false, index: true
      t.string :password_digest, null: false

      t.timestamps
    end
  end
end
# db/migrations/20201018055351_create_properties.rb

class CreateProperties < ActiveRecord::Migration[6.0]
  def change
    create_table :properties do |t|
      t.references :landlord, foreign_key: {to_table: :users}, null: false
      t.references :tenant,   foreign_key: {to_table: :users}

      t.timestamps
    end
  end
end
# db/schema.rb

ActiveRecord::Schema.define(version: 2020_10_18_055351) do

  create_table "properties", force: :cascade do |t|
    t.bigint "landlord_id", null: false
    t.bigint "tenant_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["landlord_id"], name: "index_properties_on_landlord_id"
    t.index ["tenant_id"], name: "index_properties_on_tenant_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.string "email", null: false
    t.string "password_digest", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["email"], name: "index_users_on_email"
  end

  add_foreign_key "properties", "users", column: "landlord_id"
  add_foreign_key "properties", "users", column: "tenant_id"
end