Post GeoJSON 数据和表单数据到 Rails 4 个应用
Post GeoJSON data with form data to Rails 4 app
我有一个创建 "Activity." 的网页 使用简单的表单,用户填写一些关于 activity 的基本信息:
#new.html.erb
<%= simple_form_for @activity do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<% f.button :submit, :class => "btn btn-primary" -%>
<% end %>
不过,我也在用MapBox来显示地图。用户将单击地图上的点来为 activity 制定路线。当用户完成路线绘制后,我可以为这条路线提取 GeoJSON 数据。
我想将 javascript 用于 POST 带有表单数据的 GeoJSON 数据。在后端,我将 rails 将 GeoJSON 转换为 KML 文件,并使用 Paperclip 将其上传到 Amazon S3。其余数据可以保存,Paperclip 会给我一个 URL 到 KML 文件,我可以将其与 activity.
相关联
我是一个 Rails 菜鸟,我不知道该怎么做,也不知道如何解决这个问题。我考虑过使用 javascript 的 FormData。我对这种方法很感兴趣,因为实现看起来很简单,但显然它只能真正处理 key/value 对,而不是复杂的嵌套 JSON 数据。
非常感谢任何建议或策略。如果有人能给出详细的答案,我将不胜感激,因为就像我说的,我刚刚接触 rails 和网络开发几周。
您可能想在这里做的是防止在 JS 中使用表单的默认行为:
$('form').submit(function(e) {
e.preventDefault();
var form = $('form');
var form_data_json = JSON.stringify(form.serializeArray());
form_plus_geojson = form_data_json.concat(Geojson);
在 JS 中获取数据(这应该很容易,但您并没有真正说明如何从 mapbox 中提取数据)。
然后通过AJAX发回数据(不要忘记两端验证)
if (my_data_is_not_good/empty/whatever) {
console.log('nop')
} else {
$.ajax({
type: 'post',
url: Yourcontrollerpostaction,
data: form_plus_geojson,
dataType: "JSON",
发送数据后,您希望恢复正常的表单提交 post 行为并提交表单。
complete: function() {
this.off('submit');
this.submit();
}
});
}
});
那么你只需要在你的控制器中解析数据即可。
def post_controller
if request.xhr?
my_hash = JSON.parse(params[:mydata])
else
normal post behavior
end
end
一切都是快速的伪代码,您可能需要修复一些东西,因为我还没有测试过它,但它应该可以工作。
显然,现在我们正在做 ajax 中的所有事情,您不需要完整的函数回调,可以删除那部分。
感谢@jDay 为我指明了正确的方向——特别是连接 JSON 数据。但是,我无法让他的特定解决方案在我的应用程序上运行,于是我开始尝试另一种方法,在我看来,这种方法更直接一些。
我使用 Rails simple_form_for gem 制作表格,指定远程 post 调用:
#new.html.erb
<%= simple_form_for @activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>
然后我使用 jQuery 来劫持表单提交按钮并附加一个带有 GeoJSON 数据的不可见表单元素。但是,数据必须进行字符串化才能发送:
#activity_new.js
$("form").submit( function (e) {
e.preventDefault();
$('<input />')
.attr('type', 'hidden')
.attr('name', 'routeGeoJson')
.attr('value', JSON.stringify(polyline.toGeoJSON()))
.appendTo(this);
return true;
});
(这里,"polyline"是我在地图上画的LeafletL.polyline对象。)
在控制器中,您将获得如下参数:
{"utf8"=>"✓", "activity"=>{"name"=>"A jaunt in the woods", "type"=>"walk",
"date_field"=>"2015-09-08", "time_field"=>"07:00"},
"routeGeoJson"=>"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-118.38855654001236,33.95361274499209],[-118.36624056100845,33.97681937760982]]}}",
"commit"=>"Create Activity", "controller"=>"activities",
"action"=>"create"}
由于 "routeGeoJson" 数据仍然是字符串形式,我通过使用 JSON gem(我相信包含默认在 Rails 4):
def create
geojson = JSON.parse(params[:routeGeoJson])
# do something...
end
你得到你的 GeoJSON 散列:
{"type"=>"Feature", "properties"=>{},
"geometry"=>{"type"=>"LineString",
"coordinates"=>[[-118.42014223337173, 33.98407904797006],
[-118.37825685739517, 33.956175751601826]]}}
我有一个创建 "Activity." 的网页 使用简单的表单,用户填写一些关于 activity 的基本信息:
#new.html.erb
<%= simple_form_for @activity do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<% f.button :submit, :class => "btn btn-primary" -%>
<% end %>
不过,我也在用MapBox来显示地图。用户将单击地图上的点来为 activity 制定路线。当用户完成路线绘制后,我可以为这条路线提取 GeoJSON 数据。
我想将 javascript 用于 POST 带有表单数据的 GeoJSON 数据。在后端,我将 rails 将 GeoJSON 转换为 KML 文件,并使用 Paperclip 将其上传到 Amazon S3。其余数据可以保存,Paperclip 会给我一个 URL 到 KML 文件,我可以将其与 activity.
相关联我是一个 Rails 菜鸟,我不知道该怎么做,也不知道如何解决这个问题。我考虑过使用 javascript 的 FormData。我对这种方法很感兴趣,因为实现看起来很简单,但显然它只能真正处理 key/value 对,而不是复杂的嵌套 JSON 数据。
非常感谢任何建议或策略。如果有人能给出详细的答案,我将不胜感激,因为就像我说的,我刚刚接触 rails 和网络开发几周。
您可能想在这里做的是防止在 JS 中使用表单的默认行为:
$('form').submit(function(e) {
e.preventDefault();
var form = $('form');
var form_data_json = JSON.stringify(form.serializeArray());
form_plus_geojson = form_data_json.concat(Geojson);
在 JS 中获取数据(这应该很容易,但您并没有真正说明如何从 mapbox 中提取数据)。
然后通过AJAX发回数据(不要忘记两端验证)
if (my_data_is_not_good/empty/whatever) {
console.log('nop')
} else {
$.ajax({
type: 'post',
url: Yourcontrollerpostaction,
data: form_plus_geojson,
dataType: "JSON",
发送数据后,您希望恢复正常的表单提交 post 行为并提交表单。
complete: function() {
this.off('submit');
this.submit();
}
});
}
});
那么你只需要在你的控制器中解析数据即可。
def post_controller
if request.xhr?
my_hash = JSON.parse(params[:mydata])
else
normal post behavior
end
end
一切都是快速的伪代码,您可能需要修复一些东西,因为我还没有测试过它,但它应该可以工作。 显然,现在我们正在做 ajax 中的所有事情,您不需要完整的函数回调,可以删除那部分。
感谢@jDay 为我指明了正确的方向——特别是连接 JSON 数据。但是,我无法让他的特定解决方案在我的应用程序上运行,于是我开始尝试另一种方法,在我看来,这种方法更直接一些。
我使用 Rails simple_form_for gem 制作表格,指定远程 post 调用:
#new.html.erb
<%= simple_form_for @activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>
然后我使用 jQuery 来劫持表单提交按钮并附加一个带有 GeoJSON 数据的不可见表单元素。但是,数据必须进行字符串化才能发送:
#activity_new.js
$("form").submit( function (e) {
e.preventDefault();
$('<input />')
.attr('type', 'hidden')
.attr('name', 'routeGeoJson')
.attr('value', JSON.stringify(polyline.toGeoJSON()))
.appendTo(this);
return true;
});
(这里,"polyline"是我在地图上画的LeafletL.polyline对象。)
在控制器中,您将获得如下参数:
{"utf8"=>"✓", "activity"=>{"name"=>"A jaunt in the woods", "type"=>"walk", "date_field"=>"2015-09-08", "time_field"=>"07:00"}, "routeGeoJson"=>"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-118.38855654001236,33.95361274499209],[-118.36624056100845,33.97681937760982]]}}", "commit"=>"Create Activity", "controller"=>"activities", "action"=>"create"}
由于 "routeGeoJson" 数据仍然是字符串形式,我通过使用 JSON gem(我相信包含默认在 Rails 4):
def create
geojson = JSON.parse(params[:routeGeoJson])
# do something...
end
你得到你的 GeoJSON 散列:
{"type"=>"Feature", "properties"=>{}, "geometry"=>{"type"=>"LineString", "coordinates"=>[[-118.42014223337173, 33.98407904797006], [-118.37825685739517, 33.956175751601826]]}}