views:

23

answers:

1

I have a message form which uses validates_length_of in the model to limit the length of the message.

validates_length_of   :content, :maximum => 1024

I "tested" this by entering 5k or so characters and submitted the form. But I get this NoMethodError:

NoMethodError in Messages#create

Showing app/views/messages/_messages.html.erb where line #1 raised:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
Extracted source (around line #1):

1: <%- for message in @messages -%>
2:   <div class="message">
3:     <%= link_to message.title, message %>
....

Messages#index:

def index
  @title = "chat"
  @messages = Message.paginate :page => params[:page], :per_page => 8, :order => "updated_at DESC" 
  respond_to do |format|
    format.html
  end
end

Messages#create:

def create
  @message = Message.new(params[:message])
  respond_to do |format|
    if @message.save
      record_post_time
      flash[:notice] = "Created \"#{@message.title}\""
      format.html { redirect_to(messages_url) }
    else
      format.html { render :action => "index" }
    end
  end
end

_messages.html.erb: (super ugly and needs major refactor)

<%- for message in @messages -%>
  <div class="message">
    <%= link_to message.title, message %>

    <%- if message.name.empty? -%>

    <%- else -%>   
      <span class="name">
        by 
        <%- if message.email.blank? -%>
          <%=h message.name %>
        <%- else -%>
          <a href="mailto:<%= message.email %>"><%=h message.name %></a>
        <%- end -%>
      </span>
    <%- end -%>

    <span class="time">
      active &#32;<%= timeago(message.updated_at) %>
    </span>

    <%- if message.comments.empty? -%>
      <span class="reply">
        <%= link_to 'reply', :controller => 'messages', :action => 'show', :id => message %>
      </span>
    <% else %>
      <span class="reply">
        <%= link_to pluralize(message.comments.count, 'reply'), :controller => 'messages', :action => 'show', :id => message %>
      </span>
    <%- end -%>

    <p><%= sanitize message.content,
 :tags => %w(a embed img object p param),
 :attributes => %w(allowfullscreen allowscriptaccess href name src type value) %></p>

    <% unless controller.controller_name == "tags" %>
      <%- unless message.tag_list.nil? || message.tag_list.empty? -%>
        <% message.tags.each do |t| %>
          <div class="tag"><%= link_to t.name.titleize, tag_path(t) %></div>
        <% end %>
      <%- end -%>
    <% end %>

    <%- unless message.comments.empty? -%>
      <div class="comments">
        <%= render :partial => message.firstcomments %>
        <%- if message.comments.count >= 4 -%>
          <%= link_to 'more...', :action => 'show', :id => message %>
        <%- end -%>
      </div>
    <%- end -%>
  </div>
<%- end -%>

I am not sure what exactly is going on here. Any help would be appreciated (even with the partial refactor). Thanks for reading my question.

+1  A: 

Hi When you entered 5k or so characters the Message become invalid record so on create worked else condition

else
  format.html { render :action => "index" }
end

you have render here render doesn't execute code inside action it just renders text file with your current data You haven't assigned @messages inside your create action (I suppose you also haven't done it in new) so it is nil when you render the index You should initialize it inside new or create or change render 'index' to render 'new'

Bohdan Pohorilets
Thank you, I'm not sure why it was changed to index.