M
M
Megapiharb2016-10-09 01:04:47
Ruby on Rails
Megapiharb, 2016-10-09 01:04:47

How to implement tree-like comments on the message model?

There is a message model like this:

class Message < ActiveRecord::Base
  belongs_to :user

  validates :user_id, presence: true
  validates :body, presence: true

  validates :user_name, presence: true, unless: 'user.present?'

  def user_name
    if user.present?
      user.name
    else
      super
    end
  end
end

Here is such a controller:
class MessagesController < ApplicationController

  def create
    @message = Message.new(message_params)

    if @message.save
      redirect_to root_path, alert: 'Сообщение сохранено :)'
    else
      redirect_to root_path, alert: 'Сообщение не сохранено :('
    end
    # @message.author_id = current_user.id if current_user.present?
  end

  def show
    @user = current_user
    @messages = Message.all.order(created_at: :desc)

    @new_message = @user.messages.build if current_user.present?

  end

  private

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

Form parse for `message`
<%= form_for @new_message do |f| %>

    <div class="form-field">
      <%= f.hidden_field :user_id %>

      <%= f.label :user, 'Сообщение', class: 'form-label' %>
      <%= f.text_area :body, class: 'form-textarea' %>
    </div>

    <div class="form-action buffer-both">
      <%= f.submit 'Отправить', class: 'button button-dark button-small' %>
    </div>
<% end %>

Message content output parsell:
<% message ||= nil %>

<div class="question">
  <div class="question-content">
    <div class="question-text text-lead">
      <%= message.body %>
    </div>

    <div class="question">
      <div class="question-content">
        <div class="question-text text-lead">
          <%= l(message.created_at, format: :short) %>
        </div>

        <div class="question-text_author">
          <% author = User.find(message.user_id) if message.user_id.present? %>

          <p>Автор: <%= author.name %></p>
        </div>

      </div>
    </div>
  </div>
</div>

And the `show` view
<%= render 'messages/form' if @user.present? %>

<% @messages.each do |message| %>
    <%= render partial: 'messages/message', object: message %>
<% end %>

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Andrey Demidenko, 2016-10-09
@Dem1

You can use closure_tree

# routes.rb
get '/messages/new/(:parent_id)', to: 'message#new', as: :new_message

# messages_controller.rb

def new
  @Message = Message.new(parent_id: params[:parent_id])
end

def create
  # можно(нужно) вынести в приватный метод
  if params[:message][:parent_id]
    parent = Message.find(params[:message].delete(:parent_id))
    @messaage = parent.children.build(message_params)
  else
    @messaage = Message.new(message_params)
  end

  if @message.save
    flash[:success] = 'Your message was successfully added!'
    redirect_to root_url
  else
    render 'new'
  end
end

# _form.html.erb
# Добавить
<%= f.hidden_field :parent_id %>

# show.html.erb

<%= link_to 'reply',  new_message_path(message.id) %>

C
CapeRatel, 2016-10-09
@CapeRatel

https://github.com/elight/acts_as_commentable_with...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question