假设我有电影,人物和电影人物
class Person < ActiveRecord::Base
has_many :movies_people
has_many :movies, through: :movies_people
class Movies < ActiveRecord::Base
has_many :movies_people
has_many :people, through: :movies_people
class MoviesPerson < ActiveRecord::Base
belongs_to :movie
belongs_to :person
end
表movies_people
有一个角色属性,我想在电影中存储这个人的工作。现在我可以在控制台中做这样的事情:
u = User.first
m = Movie.first
m.people << u
然后找到合适的movies_people条目并设置&#39;角色&#39;
检索看起来像这样:
m.people.where(movies_people: {role: :actor})
最好的方法是:
答案 0 :(得分:2)
一种解决方案是创建Roles
,其中包含现有角色列表和MovieRole
加入电影,人物和角色的课程。
class Movie < ActiveRecord::Base
has_many :movie_roles, class_name: "MovieRole"
has_many :roles, through: :movie_roles
has_many :people, through: :movie_roles
end
class People < ActiveRecord::Base
has_many :movie_roles, class_name: "MovieRole"
has_many :movies, through: :movie_roles
has_many :roles, through: :movie_roles
end
class Role < ActiveRecord::Base
has_many :movie_roles, class_name: "MovieRole"
has_many :people, through: :movie_roles
has_many :movies, through: :movie_roles
end
class MovieRole < ActiveRecord::Base
belongs_to :movie
belongs_to :people
belongs_to :role
end
所有关系都是movie_roles
中的商店,这是一个三向连接表:
class CreateMovieRoles < ActiveRecord::Migration
def change
create_table :movie_roles do |t|
t.references :movie, index: true
t.references :people, index: true
t.references :role, index: true
t.timestamps
end
end
end
您可以如何查询此关联的一些示例:
@roles = Movie.find_by(title: 'Godzilla').roles
@directors = People.joins(:roles).where(roles: {name: 'Director'})
@directed_by_eastwood = Movie.joins(:people, :roles)
.merge(Role.where(name: 'Director'))
.merge(People.where(name: 'Clint Eastwood'))
要将某人与电影相关联,您需要:
MovieRole.create(people: person, movie: movie, role: role)
但是你需要设置方便的方法,如:
class People < ActiveRecord::Base
def add_role(role, movie)
role = Role.find_by(name: role) unless role.is_a?(Role)
MovieRole.create(people: self, movie: movie, role: role)
end
end
class Movie < ActiveRecord::Base
def add_cast(role, person)
role = Role.find_by(name: role) unless role.is_a?(Role)
MovieRole.create(people: person, movie: self, role: role)
end
end
答案 1 :(得分:1)
要保存角色,只需:
person = Person.find(person_id)
movie = Movie.find(movie_id)
movie.movies_people.create(person: person, role: :actor)
按角色检索
movie = Movie.includes(:people).where(id: movie_id).where(movies_people: {role: :actor})
编辑:除非您需要,否则我不建议添加角色表。我遵循agile principles,在这种情况下:“简单 - 最大化未完成工作量的艺术 - 是必不可少的。”