带有Rails命名空间的可排序列表& Railscasts 147错误:无效请求:HTTP格式无效,解析失败

时间:2015-08-21 00:25:05

标签: jquery ruby-on-rails jquery-ui ruby-on-rails-4 has-many-through

我正在为Rails中的连接表构建一个可排序的功能。我有3个型号,Food,User,User_Food。食物是预先填充的常见食物。用户将他们的收藏夹添加到User_Food。我试图让用户使用JQuery Sortable来重新排序他们最喜欢的食物列表(使用User_Food表上的位置列)......但我收到了错误。我也在使用Rails Route Namespaces。

同样,我正在设置"位置"连接表上的列(User_Food)不在Food表中。

我一直关注Ryan Bates Railscast 147,我可以让拖放可排序列表的前端工作......但它并没有保存任何东西。我的踪迹只是显示了这一点:

 Invalid request: Invalid HTTP format, parsing fails.

user.rb

has_many :foods, through: :user_foods
has_many :user_foods, dependent: :destroy

food.rb

has_many :users, through: :user_foods
has_many :user_foods, dependent: :destroy

user_food.rb

belongs_to :user
belongs_to :food

的routes.rb

 namespace :profile do
    resources :user_foods do
      collection { post :sort }
    end
  end

user_foods_controller.rb

  def manage
    @user_foods = UserFood.where(user_id: current_user.id )
  end

  def sort
    params[:user_food].each_with_index do |id, index|
      UserFood.update_all({position: index+1}, {id: id})
    end
    render nothing: true
  end

manage.html.slim

ul.list-unstyled.pt30  id="user_foods" data-update-url="<%= sort_profile_user_foods_url %>"
  - @user_foods.each do |user_food|
    li
      = user_food.food.name
  = link_to 'add food to list', new_profile_user_food_path

JS

 $('#user_foods').sortable({
  axis: 'y',
  placeholder: "ui-state-highlight",
  cursor: 'move',
    update: function() {
      $.post($(this).data('update-url'), $(this).sortable('serialize'));
    }
  }).disableSelection();

已更新

 15:46:13 web.1  |   UserFood Load (0.6ms)  SELECT "user_foods".* FROM "user_foods" WHERE "user_foods"."user_id" = $1  ORDER BY "user_foods"."position" ASC  [["user_id", 1]]
    15:46:13 web.1  |   Link Load (0.7ms)  SELECT "foods".* FROM "foods" WHERE "foods"."id" IN (1, 2, 3, 4, 5, 46, 45, 47, 6, 7)
    15:46:13 web.1  |   Page Load (0.7ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 1]]
    15:46:13 web.1  |   Page Load (0.4ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 2]]
    15:46:13 web.1  |   Page Load (0.4ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 3]]
    15:46:13 web.1  |   Page Load (0.5ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 4]]
    15:46:13 web.1  |   Page Load (0.5ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 5]]
    15:46:13 web.1  |   Page Load (0.5ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 46]]
    15:46:13 web.1  |   Page Load (0.3ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 45]]
    15:46:13 web.1  |   Page Load (0.4ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 47]]
    15:46:13 web.1  |   Page Load (0.3ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 6]]
    15:46:13 web.1  |   Page Load (0.3ms)  SELECT  "pages".* FROM "pages" WHERE "pages"."id" = $1 LIMIT 1  [["id", 7]]
    15:46:13 web.1  |   Rendered admin/user_foods/edit.html.slim within layouts/admin/application (125.9ms)
    15:46:14 web.1  |   Rendered shared/_admin_header.html.slim (5.3ms)
    15:46:14 web.1  | Completed 200 OK in 213ms (Views: 179.5ms | ActiveRecord: 16.1ms)
    15:46:23 web.1  | Invalid request: Invalid HTTP format, parsing fails.

1 个答案:

答案 0 :(得分:1)

此消息通常由查询字符串中的特殊字符触发。要么在uri中,要么在url的参数部分。

为了直观地找出特殊字符的位置,请使用Web控制台输出您正在执行的部分或ajax请求:

$('#user_foods ul').each(function (i,o) { console.log(o.data('update-url')) });
$('#user_foods ul').each(function (i,o) { console.log(o.sortable('serialize')) });

我很确定你会发现你的序列化字符串不像你预期的那样。您似乎缺少在视图中包含记录ID。试试这个:

ul.list-unstyled.pt30  id="user_foods" data-update-url="<%= sort_profile_user_foods_url %>"
  - @user_foods.each do |user_food|
    li id="userfood_#{user_food.id}" # Here, jQuery sortable expect the 
                                     # format "setname_number", and it spits out 
                                     # a hash like "setname[]=number&setname[]=number".

      = user_food.food.name
  = link_to 'add food to list', new_profile_user_food_path

您可以查看serialize options,它可以帮助您控制生成的字符串