SitePoint Sponsor

User Tag List

Results 1 to 3 of 3

Hybrid View

  1. #1
    SitePoint Zealot
    Join Date
    Mar 2003
    Location
    Georgia
    Posts
    161
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Fixing no route matches for previous/next inbox function

    I am stuck on my previous/next functions for the inbox messaging. For starters on certain messages I am getting a "no route matches" error. And then in addition to that problem the previous/next links are skipping messages. It should go in order, as in if you're on message 8. The previous link should be 7, and the next link should point to 9. I have been at work on this for quite some time and can't quite get it to work.

    message model:

    Code:
    class Message < ActiveRecord::Base
    	attr_accessible :subject, :body, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
    	validates_presence_of :subject, :message => "Please enter message title"
    
    	belongs_to :sender,
    	:class_name => 'User',
    	:foreign_key => 'sender_id'
    	belongs_to :recipient,
    	:class_name => 'User',
    	:foreign_key => 'recipient_id'
    
        # marks a message as deleted by either the sender or the recipient, which ever the user that was passed is.
        # When both sender and recipient marks it deleted, it is destroyed.
        def mark_message_deleted(id,user_id)
             self.sender_deleted = true if self.sender_id == user_id
             self.recipient_deleted = true if self.recipient_id == user_id
             (self.sender_deleted && self.recipient_deleted) ? self.destroy : self.save!
         end
        # Read message and if it is read by recipient then mark it is read
        def readingmessage
          self.read_at ||= Time.now
          save
        end
        
        # Based on if a message has been read by it's recipient returns true or false.
        def read?
        	self.read_at.nil? ? false : true
        end
    
        def self.received_by(user)
           where(:recipient_id => user.id)
         end
    
         def self.not_recipient_deleted
           where("recipient_deleted = ?", false)
         end
         
         def self.sent_by(user)
            Message.where(:sender_id => user.id)
          end
          
          def previous(same_recipient = true)
            collection = Message.where('id <> ? AND updated_at > ?', self.id, self.updated_at).order('updated_at ASC')
            collection.where(recipient_id: self.recipient_id) if same_recipient
            collection.first
          end
    
          def next(same_recipient = true)
            collection = Message.where('id <> ? AND updated_at < ?', self.id, self.updated_at).order('updated_at DESC')
            collection.where(recipient_id: self.recipient_id) if same_recipient
            collection.first
          end
        end
    Messages controller

    Code:
    
    class MessagesController < ApplicationController
      
      before_filter :set_user
      
      def index
        if params[:mailbox] == "sent"
          @messages = @user.sent_messages
        elsif params[:mailbox] == "inbox"
          @messages = @user.received_messages
        #elsif params[:mailbox] == "archieved"
         # @messages = @user.archived_messages
        end
        if params[:mailbox] == "unread"
        @messages = @user.unread_messages
      end
      end
      
      def new
        @message = Message.new
        if params[:reply_to]
          @reply_to = User.find_by_user_id(params[:reply_to])
          unless @reply_to.nil?
            @message.recipient_id = @reply_to.user_id
          end
        end
      end
      
      def create
        @message = Message.new(params[:message])
        @message.sender_id = @user.id
        if @message.save
          flash[:notice] = "Message has been sent"
          redirect_to user_messages_path(current_user, :mailbox=>:inbox)
        else
          render :action => :new
        end
      end
    
      def show
         @message = Message.find(params[:id])
         @message.readingmessage if @message.recipient == current_user
       end
       
       def destroy
         @message = Message.find(params[:id])
         @message.destroy
         flash[:notice] = "Successfully deleted message."
         redirect_to user_messages_path(@user, @messages)
       end
      
      def delete_multiple
          if params[:delete]
            params[:delete].each { |id|
              @message = Message.find(id)
              @message.mark_message_deleted(@message.id,@user.id) unless @message.nil?
            }
            flash[:notice] = "Messages deleted"
          end
          redirect_to user_messages_path(@user, @messages)
      end
      
      private
        def set_user
          @user = current_user
        end
    end
    show.html

    Code:
    	 <%= link_to 'Next', user_message_path(current_user, @message.next) %>
    	  <%= link_to 'Previous', user_message_path(current_user, @message.previous) %>
    error message

    Code:
    No route matches {:action=>"show", :controller=>"messages", :user_id=>#<User id: 1, email: "admin@admin.com", password_digest: "$2a$10$dAakIwpw/FLroM3Khkm6luEb8yDJLzCxVzLTKeS7bFg8...", zip_code: "39484", birthday: "1984", name: nil, username: "admin", gender: "women", ethnicity: "1", sexuality: nil, career: "Websites", education: "5", religion: "1", politics: nil, children: "2", height: nil, user_smoke: "3", user_drink: "1", about_me: "i am the admin!", inches: "2", feet: "6", created_at: "2013-04-17 13:31:11", updated_at: "2013-05-08 17:28:08", auth_token: "LTzif2q6921TM4pQzfmEGg", password_reset_token: nil, password_reset_sent_at: nil, admin: nil, role: "admin", roles_mask: nil, age: "39", age_end: nil>, :id=>nil}
    Founder and CEO of AreYouTaken.com

  2. #2
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,108
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    The "no route matches" error is when next or previous are returning nil so the routes can't be generated without an id.

    Perhaps the simplest fix is to wrap conditionals around those links.
    Code ruby:
    <% if @message.next.present? %>
      <%= link_to 'Next', user_message_path(current_user, @message.next) %>
    <% end %>
    <% if @message.previous.present? %>
      <%= link_to 'Previous', user_message_path(current_user, @message.previous) %>
    <% end %>

    Not sure what same_recipient is being used for but these look ok to me.
    Code ruby:
    def previous
      Message.order('updated_at DESC').where('updated_at < ?', updated_at).last
    end
    def next
      Message.order('updated_at DESC').where('updated_at > ?', updated_at).first
    end
    The id's won't be next/previous as you're not ordering by id, you're ordering by the updated_at

  3. #3
    SitePoint Zealot
    Join Date
    Mar 2003
    Location
    Georgia
    Posts
    161
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for delayed response, was on vacation but now I'm back to working full-time on this project. Thanks for the assistance!

    I forgot I had it with updated it, as oppose to created at. So I switch that. But I think I'm going to try the id number instead as that would be much easier. As I think the created time goes by when the user clicks on "new message", which in some cases users will go to new message and just stay on that page while they're browsing some other page from the internet. So to get a true next/previous I probably should sort by ID. I will see what I can do about that.

    Why did the conditionals have to be wrap about it? I just want to understand the code so I know for the future.
    Founder and CEO of AreYouTaken.com


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •