У меня есть комментарии в моем проекте, и я хочу отображать их в трех, и есть желание отображать оставшиеся комментарии, также по трем ссылкам. как я могу сделать частичное, чтобы он продолжал отображать комментарии при нажатии кнопки? Помоги мне
сообщений /_comments.html.haml
.container
.row.news
.col-sm-12.news{id: "post-comments-#{post.id}"}
%h2 Users Comments
- post.comments.order(:created_at).last(3).each do |comment|
= render 'posts/comment', comment: comment
.news
%h5 Add a comment:
= form_for [post, post.comments.build], remote: true do |f|
%p
= f.text_area :text
%p
= f.submit
сообщений /_comment.html.haml
.row.news-coment
.col-sm-2
%img= image_tag comment.user.avatar.url
.col-sm-5
.panel.panel-default
.panel-heading
%strong= link_to("#{comment.user.first_name} #{comment.user.second_name}", user_path(comment.user))
%span.text-muted #{comment.created_at.strftime('%-d %B %Y, %H:%M:%S')}
.panel-body
= comment.text
комментарии /create.js.haml
$("#post-comments-#{@post.id}").append("#{escape_javascript render('posts/comment', comment: @comment)}");
Если вы создаете свой post.comment через форму и добавляете опцию remote: true, вам нужно сказать, что ваш контроллер отвечает в формате js. Я предполагаю, что это так, вы уже создали файл js.
Вам нужно добавить созданный комментарий, возможно, создать контейнер post.comments, например:
#posts-container
- post.comments.order(:created_at).last(3).each do |comment|
= render 'posts/comment', comment: comment
И ваш файл create.js почти готов:
$("#post-container").append("#{escape_javascript render('posts/comment', comment: @comment)}");
Просто не забудьте ответить в формате html и js из вашего метода контроллера, например:
...
if @comment.save
format.html { }
format.js { }
Чтобы загрузить больше комментариев при нажатии кнопки, вы можете попробовать выполнить следующие действия.
Создайте метод в текущем контроллере, который позволяет загружать следующие 3 комментария в зависимости от последнего. Вы заказываете комментарии в зависимости от их атрибута created_at (или того, что вы хотите), попросите те элементы, которые id меньше, чем переданное значение, и принимают только 3, например:
def load_comments
@comments = Comment.order(created_at: :desc).where('id < ?', params[:comment_id]).limit(3)
respond_to :js
end
Примечание: взгляните на разницу между limit
и take
.
Затем создайте маршрут GET, чтобы ответить на ваш запрос, например:
get 'load_comments', to: 'posts#load_comments' # posts was my controller, your can be anything
Затем создайте link_to
с параметром remote: true, который сделает запрос, передающий последний comment.id
, например:
<%= link_to 'Load More', load_comments_path(comment_id: @comments.last.id), remote: true, class: 'load-more' %>
Примечание. Я получаю идентификатор из последнего комментария в ActiveRecordRelationship @comments, поэтому вам также нужно определить его, в вашем случае, возможно, в вашем текущем контроллере.
По вашему мнению, когда link_to готов сделать запрос, вам нужно установить id из последнего комментария для запроса, вы можете сделать это следующим образом:
<script>
document.querySelector('.load-more').href = '/load_comments?comment_id=' + '<%= @comments.last.id %>'
</script>
И, наконец, ваш load_comments.js.erb
который отвечает на метод, выполняет итерацию над каждым comment
и отображает его, например:
<% @comments.each do |comment| %>
$("#comments-table").append('<%= j render "comments/comment", comment: comment %>')
<% end %>
document.querySelector('.load-more').href = '/load_comments?comment_id=' + '<%= @comments.last.id %>'
Также задает последний идентификатор комментария, чтобы снова выполнить запрос.
Мой файл _comment.html.erb выглядит следующим образом:
<tr>
<td><%= comment.text %></td>
<td><%= comment.post.id %></td>
</tr>
Надеюсь, это поможет вам.