我有3个模型:Books,Notifications和NotificationTypes。由于通知模型具有book_id,因此书籍会发出通知。通知具有一个notification_type,因为通知模型具有一个notification_type_id
我希望在date1和date2之间创建所有图书
books_set1 = Book.find :all, :conditions => ["created_at <= ? AND show_time >= ?", max_date, min_date]
但是我不希望有通知通知的书籍.notification_type_id = 1,理想情况下我想通过引用notification_type.name来说这个,所以我不想要有通知通知的书籍.notification_type.name ='type1 “
如果已经为一本书创建了type1的通知,我不希望它在集合中返回(因为我将使用返回的集合创建该类型的通知)。
我不确定是否有办法在一个查询中执行此操作,我认为我需要2个查询和INTERSECT - 第一个我已经包含在这篇文章中,第二个我不确定。但在伪代码中,我认为这是它需要做的事情:
notification_type_id = Notification.find_by_name('type1')
get all notifications where notification_id = notification_type_id
set2 = get the associated book set from the notification set (since each notification has one book)
然后我做set1 - set2
更新
感谢您的帮助,我写了两个查询,让我得到了理想的结果。如果有人知道怎么做,我很乐意在1个查询中:
books_in_range = Book.find :all, :conditions => ["created_at <= ? AND created_at >= ?", max_date, min_date]
books_without_these_notifications = Book.find(:all, :joins => { :notifications => :notification_type }, :conditions => ["notification_types.name = ?","type1"] )
books_to_consider = books_in_range - books_without_these_reminders
同样,我们的想法是让所有没有创建type1通知的书籍都在特定的日期范围内。
答案 0 :(得分:3)
以下内容应该有效:
Book.scoped(:conditions => ["created_at <= ? AND show_time >= ?", max_date,
min_date]).find(:all, :joins => { :notifications => :notification_types },
:conditions => ["notification_type.name <> ?", "type1"])
将一些参数提取到named_scope
或局部变量中,以便更清晰。
更新以反映否定。
答案 1 :(得分:2)
你可以用NOT EXISTS来做,但我不确定它会有多高效:
Book.find(
:all,
:conditions =>
['created_at <= ? AND show_time >= ? AND
NOT EXISTS
(SELECT * FROM notifications
INNER JOIN notification_types ON notifications.notification_type_id = notification_types.id
WHERE notification_types.name = ? AND notifications.book_id = books.id)',
max_date, min_date, 'type1'
])
您可以从不同的方向来看看,并通过向书籍或其他直接加入书籍的对象添加布尔值来跟踪那些 已发出type1通知的内容。然后您的查询可能是:
Book.find(:all,
:conditions =>
['created_at <= ? AND show_time >= ? AND
type1_notification_sent = ?',
max_date, min_date, false
])
答案 2 :(得分:0)
SELECT books.* FROM books WHERE books.created_at <= ? AND books.show_time >= ? AND
notifications.name <> 'type1'
LEFT OUTER JOIN notifications ON notifications.book_id = books.id AND
notification.name = 'type1'
这会奏效,我想。