【问题标题】:How can I clean up this Padrino AJAX call?如何清理这个 Padrino AJAX 调用?
【发布时间】:2026-01-25 03:50:02
【问题描述】:

我正在编写一个应用程序,该应用程序主要是通过 AJAX 调用后端服务器的 UI。页面加载很少。

因此,例如,当我创建行程时,我的 JS 只是将 JSON 对象发送到 Padrino(通过 POST),然后 Padrino 保存行程对象(通过 ActiveRecord)并返回 JSON 响应。

这似乎可行,但我不仅想清理代码,还想清理提交的值。

这是我的POST 代码 (trips controller)

post :index, :provides => :json do
  response = {}
  response[:trip] = {}

  begin
      @trip = Trip.new
      @trip.title = params[:trip][:title]
      @trip.description = params[:trip][:title]

      if @trip.save
          response[:status] = "Success"
          response[:trip] = {:title => @trip.title, :description => @trip.description}
          response[:message] = "#{@trip.title} successfully saved"
      else
          response[:status] = "Error"
          response[:message] = "Error saving trip"
      end
  rescue
     response[:status] = "Error"
     response[:message] = "Error saving trip"
  end

  response.to_json
end

目前,只有两个字段(标题和描述),但完成后大约会有 4-8 个字段。我不喜欢我构建新行程对象的方式。

我尝试使用:

@trip = Trip.build(params[:trip])

但这没有用。

这是我发送 POST 的 JS 代码:

// Save new trip
$("#new_trip_save_btn").click(function() {
    var self = this;
    var new_trip = get_new_trip();

    $.ajax({
        data: {trip:new_trip},
        dataType: "json",
        url: "/trips",
        type: "post", 
        success: function(res) {
            console.log(res)
        }
    });
});

......

var get_new_trip = function() {
    var self = this;
    var trip = {};
    trip.title = $("#new_trip_title").val();
    trip.description = $("#new_trip_description").val();
    trip.departure_date = $("#new_trip_departure").val();
    trip.return_date = $("#new_trip_return").val();

    return trip;
}

那么我可以做些什么来清理代码(删除 POST 操作中的冗余)并确保在保存之前对文本进行清理。

谢谢

【问题讨论】:

    标签: jquery sinatra http-post padrino


    【解决方案1】:

    首先,您应该使用 attr_accessible 和 attr_protected aka mass assignment 保护您的模型免受大规模分配。

    然后我强烈建议使用“表单”,这样您的网站就可以在没有启用 javascript 的情况下运行。

    所以使用unobtrusive javascripts 代码也可以更好。

    // Live watch events on form submit
    $(document).on('submit', 'form[data-remote]', function(e){
      e.preventDefault();
      self = $(this);
      $.ajax({
        url: self.attr('action'),
        data: self.serializeArray(),
        type: self.attr('method'),
        dataType: 'json',
        success: function(res){ console.log(res) }
      })
    });
    

    这里是表格:

    /* Here the form, for dates I suggest to use a calendar */ 
    /* like https://github.com/arshaw/fullcalendar */
    - form_for @trip, url(:trip, :index), :'data-remote' => true do |f|
      == f.error_messages
      == f.text_field :title
      == f.text_area :description
      == f.text_field :departure_date
      == f.text_field :return_data
      == f.submit 'Send'
    

    这里是控制器:

    provides :json # if all your actions in your controller respond to #json it is more dry
    
    get :index do
      @trip = Trip.new(params[:trip])
    
      if @trip.save
        render :success => true, :attributes => @trip.to_json
      else
        render :success => false, :errors => @trip.errors.full_messages
      end
    end
    

    【讨论】:

    • 感谢您的回复。但是,我的逻辑是使用 nginx 渲染静态页面,并简单地使用 Padrino 作为后端。我将在 JS UI 上花费大量时间,因此没有 JS 意味着无法访问。有些人不喜欢。但是来吧……现在是 2012 年。哈哈。你对用 Backbone 替换我的自定义 JS ajax 帖子有什么想法?
    • 视情况而定,Backbone 是一个不错的选择,但如果应用程序逻辑不是那么复杂,最好从头开始编写几行 js。我的代码“实时”监视所有具有“数据远程”属性的表单并将其转换为 ajax 请求。这是一个“标准”的 rails-ujs/padrino-ujs 调用,总是有用的。
    • Backbone 非常真实。我实际上是在 nginx 将提供的一个 HTML 页面中呈现 index/new/edit 表单。然后,我会根据您要执行的操作隐藏每个部分。使它看起来页面加载是瞬时的。 :-)