ruby-on-railsactionview

Could you explain this syntax that I found in a tutorial? <%= link_to 'Show Previous', '?m=all' %>


I was following a tutorial, and found the following which is now in my app/views/message/index.html.erb

<%= link_to 'Show Previous', '?m=all' %>

I've never seen the '?m=all' part before, and am trying to understand how it works.

The relevant controller in app/controllers/messages_controller.rb is below

def index
    @messages = @conversation.messages
    if @messages.length > 10
      @over_ten = true
      @messages = @messages[-10..-1]
    end
    if params[:m]
      @over_ten = false
      @messages = @conversation.messages
    end
    if @messages.last
      if @messages.last.user_id != current_user.id
        @messages.last.read = true;
      end
    end

    @message = @conversation.messages.new
  end

Where is params[:m] getting params from? The only path it receives from is the conversation_messages_path(@conversation) helper path, and the MessagesController has a params of

 def message_params
        params.require(:message).permit(:body, :user_id)
    end

Additionally, inside of the controller (line 13)... @messages.last.read = true; also doesn't make sense to me. My Message class has a boolean for it's #read method, but it's not saving the method, and there is a semicolon which I don't see anywhere else in the code of the tutorial.


Solution

  • Short

    Your m variable comes from query string parameter.

    More

    Signature of link_to helper method is

    link_to(name = nil, options = nil, html_options = nil, &block)

    Creates an anchor element of the given name using a URL created by the set of options. See the valid options in the documentation for url_for. It’s also possible to pass a String instead of an options hash, which generates an anchor element that uses the value of the String as the href for the link.

    According to your case it renders link to your messages#index path (current page):

    http://your_host:port/messages?m=all

    You can rewrite your link_to example such way:

    link_to 'Show Previous', messages_path(m: 'all')

    and result will be same.

    Okay, let's go further.

    ...
    if params[:m]
      @over_ten = false
      @messages = @conversation.messages
    end
    ...
    
    

    There is a simple presence check for m parameter, so if you change value all to something another, like foo or blabla the result still be the same.

    Semicolon isn't necessary, because you have just a new line after line with it

    Ruby interprets semicolons and newline characters as the ending of a statement. However, if Ruby encounters operators, such as +, −, or backslash at the end of a line, they indicate the continuation of a statement.