如何在保留params的同时通过AJAX表单将params传递给create.js?

时间:2015-05-15 20:22:33

标签: ruby-on-rails ajax params

我有一些评论有投票得分,我使用切换过滤最近和流行。当我点击热门时,它会传递sort:popular as params,并根据它来评论评论列表。然后当用户使用AJAX发布另一个评论时,我试图通过将排序参数通过评论表单传递给控制器​​来保持评论按流行排序(而不是恢复到默认的最近),然后创建。 js,它根据params传入对评论进行排序。这个工作一次,但是一发布2条评论,它就会恢复到最近排序,因为我无法继续传递排序参数。

我的切换:

<% if params[:sort] == 'popular' %>
    sorted by <%= link_to("Recent", video_path(video), remote: true, class: 'gray-link') %> |
    <%= link_to("POPULAR", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% else %>
    sorted by <%= link_to("RECENT", video_path(video), remote: true, class: 'gray-link') %> |
    <%= link_to("Popular", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% end %>

注释形式,我将params作为隐藏字段传递:sort - note,它们是嵌套注释,因此是form_for语法,但它应该与此无关。

<%= form_for [@video, @comment, , :html => {:class => 'form_height'}], :remote => true, method: :post, url: video_comments_path(@video.id) do |f| %>
    <div id="comment-form-errors">
        <%= render :partial => "/videos/comment_form_errors" %>
    </div>

    <%= f.hidden_field :parent_id, :value => parent_id %>
    <%= f.hidden_field :sort, value: params[:sort] %>
    <%= f.text_area :post, placeholder: 'Comment', id: 'comment-box' %>

    <% if parent_id != nil %>
        <%= f.submit "Reply" %>
    <% else %>
        <%= f.submit %>
    <% end %>
<% end %>

然后在控制器中我创建一个变量@sort来从评论表单中收集排序参数:

def create
        @comment = @video.comments.build(comment_params)
        @comment.user = current_user
        @sort = params[:comment][:sort]

        respond_to do |format|
            if @comment.save
                format.html { redirect_to video_path(@video.id), notice: "You said something. Let's hope it didn't suck." }
                format.js { }
            else
                format.html { render 'videos/show', alert: "There was an error." }
                format.js {}
            end
        end
    end

然后我根据流行的排序参数是否通过来命令评论:

<% if @comment.errors.present? %>
    $('#comment-form-errors').html("<%= escape_javascript(render(:partial => '/videos/comment_form_errors')) %>");
<% else %>
    <% if @sort == 'popular' %>
        $('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'cached_weighted_score DESC') %>");
    <% else %>
        $('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'created_at DESC') %>");
    <% end %>

    $('#review-form-errors').html('');
    $('textarea#comment-box').val('');
    $('#comment-counter').text("<%= pluralize(@video.comments.count, 'comment') %>");   
    $('.error-explanation').text('');
<% end %>

这里的问题:我的服务器日志第一次显示params被发送为:参数:{&#34; utf8&#34; =&gt;&#34;✓&#34;,&# 34;评论&#34; =&gt; {&#34; parent_id&#34; =&gt;&#34; 321&#34;,&#34;排序&#34; =&gt;&#34;热门&#34;, &#34;发布&#34; =&gt;&#34; c&#34;},&#34;提交&#34; =&gt;&#34;回复&#34;,&#34; video_id&#34; = &gt;&#34; 283&#34;} - 这很棒,我发表评论和评论,如果按热门排序,请保持按热门排序。

但是,如果我连续发表第二条评论,它就没有通过排序参数:参数:{&#34; utf8&#34; =&gt;&#34;✓&#34;,&#34 ;评论&#34; =&gt; {&#34; parent_id&#34; =&gt;&#34; 322&#34;,&#34;排序&#34; =&gt;&#34;&#34;,& #34;发布&#34; =&gt;&#34; d&#34;},&#34;提交&#34; =&gt;&#34;回复&#34;,&#34; video_id&#34; =&gt; ;&#34; 283&#34;} - 我的评论恢复为默认排序,最近。

我不知道从哪里开始。我觉得我错过了一些小事,但没有多少搜索找到了解决方案。任何人都可以指出我正确的方向,我真的很感激任何关于如何使这个工作的想法,或者如果需要,如果有更好的方法,如何重做我的解决方案。

谢谢!

编辑:在MravAtomski的帮助下,我能够实现这一目标。我将评论表改为:

<% if params[:comment] %>
    <%= f.hidden_field :sort, value: params[:comment][:sort] %>
<% else %>
    <%= f.hidden_field :sort, value: params[:sort] %>
<% end %>

在我的评论控制器中创建了我添加的动作:

if params[:sort]
    @sort = params[:sort]
elsif params[:comment][:sort]
    @sort = params[:comment][:sort]
end

1 个答案:

答案 0 :(得分:0)

我的猜测是,在第一个表单提交后排序&#39;隐藏字段会丢失它的值,因此它不会在下次提交时发送。

<%= f.hidden_field :sort, value: params[:sort] %>

也许应该是

<%= f.hidden_field :sort, value: params[:comment][:sort] %>

因为在form_for中使用了注释对象。

也可能不是这种情况,但检查它是否正在执行ajax请求而不是html请求。如果它正在进行html请求,那么它可能会失去排序&#39;由于页面刷新而产生的隐藏值。

修改

所以当页面加载时它使用params [:sort]然后在创建提交后使用params [:comment] [:sort],也许这样的东西可以用作快速解决方案:

<%= f.hidden_field :sort, value: params[:sort] || params[:comment][:sort] %>

其他解决方案是将数据属性添加到未通过create ajax request更改的其中一个标记。即表格标签。添加数据排序属性以形成用于创建注释的标记:

<%= form_for [@video, @comment, , :html => {:class => 'form_height ..., :data-sort => params[:sort] do |f| %>

创建评论时不要更改数据属性,只应在用户更改排序时设置,并在每次需要排序值时将其作为ajax请求参数发送。