我有以下型号:
class Message < ActiveRecord::Base
has_many :read_messages
module Scopes
def by_read_status(read_status, user_id)
case read_status
when 'Unread'
when 'Read'
joins(:read_messages).where(:read_messages => {:read => true, :admin_user_id => user_id})
else
where('1 = 1') # no scope necessary
end
end
end
extend Scopes
end
和...
class ReadMessage < ActiveRecord::Base
has_many :admin_users
has_many :messages
end
我有一个名为“mark_as_read”的控制器方法用于消息。它只是使用该消息 ID 和标记为已读的人的管理员用户 ID 创建一个新的 read_message 记录。由于消息是全局的,我希望系统的每个用户能够单独管理读取状态(这就是为什么我在那里有那个额外的层)。因此,正如您在我的范围内看到的那样, by_read_status('Read', user_id) 将返回它找到读取为 true 的映射记录的所有记录。问题是,我该怎么做相反的事情?(返回未找到地图记录的所有记录,或者地图记录 :read 设置为 false)?
我正在使用这样的范围:
@search = Message.search(params[:q])
messages = @search.result.accessible_by(current_ability)
messages = messages.by_company(session[:company_filter]) if session[:company_filter] && session[:company_filter] > 0
messages = messages.by_campaign(session[:campaign_filter]) if session[:campaign_filter] && session[:campaign_filter] > 0
read_filter = params[:read].blank? ? 'Unread' : params[:read]
messages = messages.by_read_status(read_filter, current_admin_user.id)
messages = messages.page(params[:page]).per(20)
@messages = MessageDecorator.new(messages)
所以你可以在我的范围中间看到,我有 by_read_status。如果我返回一个数组,或者一个范围对象以外的东西,它会抛出一个合适的。谁能帮我弄清楚如何做我范围的“未读”部分?
谢谢!
编辑后的答案
exclude = Message.by_read_status('Read', user_id).map(&:id)
exclude = [0] unless exclude.size > 0
where("id not in (?)", exclude)