Frage

I have the following models:

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

and...

class ReadMessage < ActiveRecord::Base

  has_many :admin_users
  has_many :messages

end

I have a controller method called 'mark_as_read' for the message. It just creates a new read_message record with that message id, and the admin user id of the person that marked as read. Since messages are global, I want the ability for each user of the system to manage the read status seperately (which is why I have that extra layer in there). So as you can see by my scope, the by_read_status('Read', user_id) would return all records where it finds a mapped record with read true. The problem is, how can I do the opposite? (return all records where it does not find a map record, OR the map record :read is set to false)?

I am using the scopes like this:

@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)

So you can see in the middle there of my scopes, i've got the by_read_status. If I return an array, or something other than a scoped object, it will throw a fit. Can anyone help me figure out how to do the 'Unread' portion of my scope?

Thanks!

Edited Answer

exclude = Message.by_read_status('Read', user_id).map(&:id)
exclude = [0] unless exclude.size > 0

where("id not in (?)", exclude)
War es hilfreich?

Lösung

where("id not in (?)", by_read_status('Read', user_id))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top