ruby-on-rails 基于“事件”模型创建自定义友谊关联

piwo6bdm  于 2023-02-14  发布在  Ruby
关注(0)|答案(2)|浏览(98)

我一直在研究使用角色、自定义关联等的友谊模型,但我还不能以一种清晰的方式将我的项目与概念联系起来。
我希望一个“用户”能够创建一个事件,我称之为“收集”。一个用户也可以参加由其他用户创建的收集。通过参加收集,“用户”也可以是一个“收集者”。
采集者的名单在技术上会被认为是“创造者”的朋友。这是我目前的进展:
型号:用户聚集聚集器(?)
用户

class User < ApplicationRecord
    has_many :gathers_as_creator,
        foreign_key: :creator_id,
        class_name: :Gather
    
    has_many :gathers_as_gatherer, 
        foreign_key: :gatherer_id,
        class_name: :Gather
    

end

聚集

class Gather < ApplicationRecord

    belongs_to :creator, class_name: :User 
    belongs_to :gatherer, class_name: :User

end

我的问题是,我是否需要一个连接表(如Gatherer)来允许多个与会者,然后再为用户/创建者拉取一个朋友列表?
采集器

belongs_to :gather_attendee, class_name: "User" 
belongs_to :attended_gather, class_name: "Gather"

下面是我所认为的模式:

create_table "gatherers", force: :cascade do |t|
    t.bigint "attended_gather_id"
    t.bigint "gather_attendee_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["attended_gather_id"], name: "index_gatherers_on_attended_gather_id"
    t.index ["gather_attendee_id"], name: "index_gatherers_on_gather_attendee_id"
  end

救命,我的头在旋转试图理解的连接和如何进行。
既往计划:
模式:

create_table "activities", force: :cascade do |t|
    t.string "a_type"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "gatherers", force: :cascade do |t|
    t.bigint "attended_gather_id"
    t.bigint "gather_attendee_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["attended_gather_id"], name: "index_gatherers_on_attended_gather_id"
    t.index ["gather_attendee_id"], name: "index_gatherers_on_gather_attendee_id"
  end

  create_table "gathers", force: :cascade do |t|
    t.integer "creator_id"
    t.integer "activity_id"
    t.text "gather_point"
    t.boolean "active"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "interest_gathers", force: :cascade do |t|
    t.string "gather_id"
    t.string "interest_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "interests", force: :cascade do |t|
    t.string "i_type"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "img"
    t.string "first_name"
    t.string "last_name"
    t.string "state"
    t.string "city"
    t.string "bio"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  add_foreign_key "gatherers", "gathers", column: "attended_gather_id"
  add_foreign_key "gatherers", "users", column: "gather_attendee_id"
end
class User < ActiveRecord::Base 
  has_many :gatherers, foreign_key: gather_attendee_id
  has_many :attended_gathers, through: :gatherers
  has_many :created_gathers, foreign_key: :creator_id, class_name: "Gather"
 end
class Gather < ActiveRecord::Base 
  has_many :gatherers, foreign_key: :attended_gather_id 
  has_many :attendees, through: :gatherers, source: :gather_attendee 
  belongs_to :creator, class_name: "User" 
end
class Gatherer < ActiveRecord::Base 
  belongs_to :gather_attendee, class_name: "User" 
  belongs_to :attended_gather, class_name: "Gather" 

end
qoefvg9y

qoefvg9y1#

这里的命名并不是很好。当给你的模型命名时,选择名词作为模型代表你的业务逻辑中的实际事物-选择动词/副词会使你的关联的名称非常混乱。

class User < ApplicationRecord
  has_many :gatherings_as_creator, 
    class_name: 'Gathering',
    foreign_key: :creator_id
  has_many :attendences
  has_many :gatherings, 
    through: :attendences
end

# think of this kind of like a ticket to an event
# rails g model Attendence user:references gathering:references
class Attendence < ApplicationRecord
  belongs_to :user
  belongs_to :gathering
end

# this is the proper noun form of gather
class Gathering < ApplicationRecord
  belongs_to :creator, 
    class_name: 'User'
  has_many :attendences
  has_many :attendees,
    though: :attendences,
    class_name: 'User'
end

我的问题是,我是否需要一个连接表(如Gatherer)来允许多个与会者,然后再为用户/创建者拉取一个朋友列表?
是的。你总是需要一个连接表来创建多对多的关联。Gatherer是一个非常容易混淆的名字,虽然它是一个收集东西的人。
如果您想让用户参加由给定用户创建的聚会,您可以通过以下方式执行此操作:

User.joins(attendences: :groups)
    .where(groups: { creator_id: user.id })
xxslljrj

xxslljrj2#

你的思路是对的。
如果我没理解错的话,你想要一个Gather有很多Users,而一个User有很多Gather(对于参与者来说),所以你需要一个如下的连接表(这和你的Gatherers表类似,但是是一个更传统的Rails风格):

create_join_table :gathers, :users do |t|
  t.index [:gather_id, :user_id]
  t.index [:user_id, :gather_id]
end

然后你会希望你的用户模型是这样的:
x一个一个一个一个x一个一个二个x
(You如果确实需要,我可以通过指定额外的选项来更改:users关联的名称--我只是希望尽可能地保持Rails的默认值。)
这应该是你所需要的大部分。如果你想拉一个创建者的所有朋友到一个特定的集合,你只需要做gather.users。如果你想拉一个创建者的所有朋友到他们所有的集合,这将是:

creator = User.find(1)
friends = User.joins(:gathers).where(gathers: { creator: creator }).all

相关问题