Rails 4:使用AJAX仅更新一个参数的自定义操作

在我的Rails 4应用程序中,我有一个CalendarPost模型,使用shallow路线:

 resources :calendars do resources :posts, shallow: true end 

日历has_manypost和postbelong_to日历。

我已经在show.html.erb视图中的post show.html.erb操作上使用AJAX调用来更新post的自定义:approval参数:

  • 我有respond_to do |format| format.js end respond_to do |format| format.js end在我的Posts#Update respond_to do |format| format.js end控制器中结束
  • 我在app/views/posts/有一个update.js.erb视图,用于重新加载后期show.html.erb视图的相应部分
  • 当然,我的链接设置为remote: true

现在,我需要实现一个类似的function,来更新post的自定义:approval参数,但是从日历 show.html.erb视图中显示所有post。

这是我目前在我的日历 show.html.erb视图中的内容:

        post.id, "post[approval]" => "ok"), remote: true, :method => :patch do %>   
post.id, "post[approval]" => "edit"), remote: true, :method => :patch do %>
post.id, "post[approval]" => "remove"), remote: true, :method => :patch do %>

此代码允许我实际更新日历 show.html.erb的post自定义:approval参数。

但我无法弄清楚如何重新加载页面,甚至更好,只需重新加载链接所在的post_approval_section td

我无法重复使用我在show.html.erb上使用的完全相同的方法,因为我已经为Posts#Update操作设置提供了JS响应。

我怎样才能做到这一点?

—–

更新 :根据Long Nguyen的回答,这里是我现在的位置。

 #calendars/show.html.erb and calendars/_post_approval.html.erb        post.id, "post[approval]" => "ok"), remote: true, approval_update: true, :method => :patch do %>   
post.id, "post[approval]" => "edit"), remote: true, approval_update: true, :method => :patch do %>
post.id, "post[approval]" => "remove"), remote: true, approval_update: true, :method => :patch do %> #posts_controller.rb def update if params["approval_update"] respond_to do |format| format.js { render :action => "update_post_approval" } end else respond_to do |format| if @post.update(post_params) format.html { redirect_to post_path(@post) } format.json { render :show, status: :ok, location: @post } format.js else format.html { render :edit } format.json { render json: @post.errors, status: :unprocessable_entity } end end end end def update_post_approval respond_to do |format| format.js end end #update_post_approval.js.erb $('td.post_approval_section').html('');

当我点击其中一个链接更新post批准时,浏览器中没有任何反应。

但是,在log/development.log ,我有:

 Started PATCH "/posts/42?post%5Bapproval%5D=edit" for ::1 at 2015-11-19 19:59:51 -0800 Processing by PostsController#update as JS Parameters: {"post"=>{"approval"=>"edit"}, "id"=>"42"} [1m[36mUser Load (1.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1[0m [["id", 1]] [1m[35mPost Load (2.2ms)[0m SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT 1 [["id", 42]] [1m[36m (1.1ms)[0m [1mBEGIN[0m [1m[35mSQL (1.1ms)[0m UPDATE "posts" SET "approval" = $1, "updated_at" = $2 WHERE "posts"."id" = $3 [["approval", "edit"], ["updated_at", "2015-11-20 03:59:51.203371"], ["id", 42]] [1m[36mSQL (3.6ms)[0m [1mINSERT INTO "versions" ("event", "object", "whodunnit", "created_at", "object_changes", "item_id", "item_type") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"[0m [["event", "update"], ["object", "---\nid: 42\ncalendar_id: 8\ndate: 2015-11-19 20:19:00.000000000 Z\nsubject: Armistice 2\nformat: Image\ncopy: Joyeux 11 novembre tout le monde. ++\ncreated_at: 2015-11-19 20:19:58.244685000 Z\nupdated_at: 2015-11-20 03:59:44.073894000 Z\nimage_file_name: armistice.jpg\nimage_content_type: image/jpeg\nimage_file_size: 35967\nimage_updated_at: 2015-11-19 20:19:57.792047000 Z\nshort_copy: etg'tg' <<\nscore: \nfacebook: true\ntwitter: true\ninstagram: false\npinterest: false\ngoogle: false\nlinkedin: false\ntumblr: \nsnapchat: \napproval: ok\n"], ["whodunnit", "1"], ["created_at", "2015-11-20 03:59:51.203371"], ["object_changes", "---\napproval:\n- ok\n- edit\nupdated_at:\n- 2015-11-20 03:59:44.073894000 Z\n- 2015-11-20 03:59:51.203371000 Z\n"], ["item_id", 42], ["item_type", "Post"]] [1m[35m (2.0ms)[0m COMMIT Rendered posts/_approval.html.erb (0.6ms) Rendered posts/update.js.erb (2.1ms) Completed 200 OK in 59ms (Views: 10.9ms | ActiveRecord: 11.1ms) 

我在这做错了什么?

—–

我想出了两个想法来处理这种情况:

第一种方式:当你从日历 show.html.erb更新post时传递另一个参数,所以link_to将是:

 <%= link_to post_path(:id => post.id, "post[approval]" => "remove", approval_update: true), remote: true, :method => :patch do %> 

然后在您发布update操作的控制器,您可以通过approval_update参数过滤此请求:

 if params["approval_update"] respond_to do |format| format.js { render :action => "update_post_approval" } end else respond_to do |format| ... end end 

现在当您从日历 show.html.erb更新Post时,Post控制器将加载RAILS_ROOT/app/views/posts/update_post_approval.js.erb而不是update.js.erb

第二种方式 :创建另一条路径来更新Post的批准属性,这意味着你还将在Post控制器中创建另一个动作来处理Calendar页面中AJAX更新的情况。

我认为你应该能够用js.erb中的条件来做到这一点:

 <% if @post.approval === 'ok' %> $('td.post_approval_section').replaceWith("<%= j render(:partial => 'calendar/approval') %>"); <% else %> // you current update post code <% end %> 

以及将代码移动到_approval.html.erb

  <% if post.approval == "ok" %>  <% else %>  <% end %> <%= link_to post_path(:id => post.id, "post[approval]" => "ok"), remote: true, :method => :patch do %>  <% end %> 
<% if post.approval == "edit" %> <% else %> <% end %> <%= link_to post_path(:id => post.id, "post[approval]" => "edit"), remote: true, :method => :patch do %> <% end %>
<% if post.approval == "remove" %> <% else %> <% end %> <%= link_to post_path(:id => post.id, "post[approval]" => "remove"), remote: true, :method => :patch do %> <% end %>

希望有所帮助。