Ruby on rails 获取多模型关联的唯一性
有三种模式:Ruby on rails 获取多模型关联的唯一性,ruby-on-rails,ruby,Ruby On Rails,Ruby,有三种模式: # Table name: activities_people # # activity_id :integer not null # person_id :integer not null # date :date not null # id :integer not null, primary key # # Table name: activities #
# Table name: activities_people
#
# activity_id :integer not null
# person_id :integer not null
# date :date not null
# id :integer not null, primary key
#
# Table name: activities
#
# id :integer not null, primary key
# name :string(20) not null
# description :text
# active :boolean not null
# day_of_week :string(20) not null
# start_on :time not null
# end_on :time not null
第三种模式是人。
协会:
class Activity < ActiveRecord::Base
has_many :activities_people
has_many :people, through: :activities_people
end
class ActivitiesPerson < ActiveRecord::Base
belongs_to :person
belongs_to :activity
end
class Person < ActiveRecord::Base
has_many :activities, through: :activities_people
end
类活动
问题:
我不知道如何在ativities_person.rb中创建验证方法来保护及时重叠的活动的参与
例如:
人员id:1参加活动,活动日期为2016年8月8日,持续时间为09:00(开始时间)-10:00(结束时间)。
同一个人希望保存到另一个活动,该活动也将是2016年8月8日,持续09:30(开始)-10:30(结束)。现在
验证应该抛出他在同一时间保存到其他活动的错误(时间范围重叠)。验证首先应检查日期是否匹配,其次应检查活动的时间重叠
我尝试的是:
def check_join_client
# check if client joined to some activities in same date as current join
activities_date = person.activities_people.where(date: date)
if activities_date.any?
# get start_on and end_on for current activity and date
get_activities = person.activities.where(id: activities_date.pluck(:activity_id))
ol_activities = get_activities.where('((start_on <= :start_on AND
end_on >= :end_on) OR
(start_on <= :start_on AND
end_on <= :end_on AND
end_on >= :start_on) OR
(start_on >= :start_on AND
start_on <= :end_on AND
end_on >= :end_on))',
start_on: get_activities.pluck(:start_on),
end_on: get_activities.pluck(:end_on))
end
end
def check\u join\u客户端
#检查客户端是否在与当前加入相同的日期加入了某些活动
活动\日期=人。活动\人。其中(日期:日期)
有什么活动吗?
#获取当前活动和日期的开始和结束时间
get\u activities=person.activities.where(id:activities\u date.pull(:activity\u id))
ol_activities=get_activities.where('((start_on=:end_on))或
(开始时=:开始时和
start_on=:end_on)),
开始:获取活动。拔出(:开始),
结束:获取活动。弹拨(:结束)
结束
结束
我的方法不对。我不知道如何解决我的问题。根据您的数据库类型,我认为Postgres有一个重叠功能,您可以使用它来进行此类查询 结果查询可能类似于:
Activity.where("(start_on, end_on) OVERLAPS (?, ?)", start_on, end_on)
另一种有点不确定DB的方法,但我无法测试:
Activity.find_by_sql("SELECT e1.* FROM activities e1, activities e2 WHERE(e2.end_on >= e1.start_on AND e2.start_on < e1.start_on)")
如果我能帮上忙,请告诉我。根据您的数据库类型,我认为Postgres有重叠功能,您可以使用该功能进行此类查询 结果查询可能类似于:
Activity.where("(start_on, end_on) OVERLAPS (?, ?)", start_on, end_on)
另一种有点不确定DB的方法,但我无法测试:
Activity.find_by_sql("SELECT e1.* FROM activities e1, activities e2 WHERE(e2.end_on >= e1.start_on AND e2.start_on < e1.start_on)")
如果我能帮上忙,请告诉我。这是一个不错的建议,但并不完全是我想要的。我仍然不知道如何创建适当的方法来获得适当的唯一性。我不太明白你所说的适当的唯一性是什么意思,但我添加了验证以确保不会创建重叠事件。对于活动,我有检查重叠的方法,这取决于池区。我要一个人登记。我不能加入重叠的活动,例如活动1在a区a区b区活动2,时间和日期相同,如果我加入活动1,我不能加入第二个。@oeroluwa。我对你的代码有问题。错误:
error:function pg_catalog.重叠(没有时区的时间,没有时区的时间,未知,未知)不是唯一的
这是一个很好的提示,但不是我想要的。我仍然不知道如何创建适当的方法来获得适当的唯一性。我不太明白你所说的适当的唯一性是什么意思,但我添加了验证以确保不会创建重叠事件。对于活动,我有检查重叠的方法,这取决于池区。我要一个人登记。我不能加入重叠的活动,例如活动1在a区a区b区活动2,时间和日期相同,如果我加入活动1,我不能加入第二个。@oeroluwa。我对你的代码有问题。错误:error:function pg_catalog.重叠(没有时区的时间、没有时区的时间、未知、未知)不是唯一的