如何从一个模型查询对象,从另一个模型开始?鲁比



我试图建立一个无效的关联。我有以下范围:

ActiveRecord::Schema.define(version: 2020_04_05_125812) do
create_table "accounts", force: :cascade do |t|
t.string "social_network"
t.string "name_account"
t.integer "person_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["person_id"], name: "index_accounts_on_person_id"
end
create_table "lists", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "lists_people", id: false, force: :cascade do |t|
t.integer "list_id", null: false
t.integer "person_id", null: false
end
create_table "people", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "posts", force: :cascade do |t|
t.string "post_text"
t.date "date"
t.string "link"
t.integer "account_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["account_id"], name: "index_posts_on_account_id"
end
add_foreign_key "accounts", "people"
add_foreign_key "posts", "accounts"
end

我希望我可以咨询,例如:我想咨询名为"Test_name"的人

这个人属于列表,列表是一组人。此外,那个人有账户,这些账户有帖子。

class List < ApplicationRecord
has_and_belongs_to_many :people  
end
class Person < ApplicationRecord
has_and_belongs_to_many :lists
end
class Account < ApplicationRecord
has_many :posts
belongs_to :person
end

class Post < ApplicationRecord
belongs_to :account 
end

我怎么能得到下面这样的退货:

List | Name      | social_network
1    | Test_name | facebook
2    | Test_name | twitter

我所做的所有查询要么返回错误的类型,要么只返回列表。问题如:

List | Name          | social_network
1    | Test_name     | facebook
2    | Test_name     | twitter
1    | Second_name   | twitter

我不想看到数据"second_name">

我试试这个:

@lists = List.from(
Person.left_outer_joins(:list).where('people.name LIKE ?',  "Renata Rempel"),
:list
)

但是,不起作用=/

首先,您需要在Person和List之间建立多对多关联。has_and_belongs_to_many可以做到这一点,但has_many through:可能是更好的选择有很多原因。主要的一点是,它可以让你添加一些功能,比如跟踪被禁止的用户或用户何时加入列表。

# rails g model list_membership member:belongs_to user:belongs_to
class ListMembership < ApplicationRecord
belongs_to :member, class_name: 'Person'
belongs_to :list
end

然后我们必须修复关联中的外键:

class CreateListMemberships < ActiveRecord::Migration[6.0]
def change
create_table :list_memberships do |t|
t.belongs_to :list, null: false, foreign_key: true
t.belongs_to :member, null: false, foreign_key: { to_table: :people }
t.timestamps
end
# can be a good idea to add a compound index
# add_index [:list_id, :member_id], unique: true
end
end
class Person < ApplicationRecord
has_many :list_memberships, foreign_key: :member_id
has_many :lists, through: :list_memberships
has_many :accounts
has_many :posts, through: :accounts
end
class List
has_many :list_memberships
has_many :members, 
through: :list_memberships
end

您的from查询不会像您实际从people中选择行那样工作,但您只是将表别名为lists。这不会神奇地选择正确的数据!如果你真的想使用从你会做:

List.from(
List.joins(:members).where("people.name LIKE ?", "Renata Rempel"),
:lists
).eager_load(members: :posts)

如果你想在种子文件中创建一组随机成员的列表,你只需要做:

ids = 10.times.map do
Person.create!(name: Faker::Name.name).id
end
lists = 10.times.do
List.create!(member_ids: ids.sample(2))
end

最新更新