我有一个像这样的隐藏表格:
= form_for movie, 'create', method: 'POST' do |f|
- Movie.attribute_names.each do |attr|
= f.hidden_field attr.to_sym, value: movie.send(attr)
= f.submit 'Save this Movie', class: 'button'
这些属性中的一些是序列化数组,但是padrino似乎不是从字符串解析数组,所以当我尝试从存储在params中的这个attr哈希中保存记录时,db会引发序列化错误:
{"title"=>"Iron Man 2",
"directors"=>"[\"Jon Favreau\"]",
"cast_members"=>"[\"Robert Downey Jr.\", \"Gwyneth Paltrow\", \"Don Cheadle\", \"Scarlett Johansson\", \"Sam Rockwell\"]",
"genres"=>"[\"Action\", \"Adventure\", \"Sci-Fi\"]",
"length"=>"124",
"trailer_url"=>"http://imdb.com/video/screenplay/vi1172179225/",
"year"=>"2010",
"languages"=>"[\"English\", \"French\", \"Russian\"]"}
我可以用这个丑陋的代码块解析数组字符串:
Movie.serialized_attributes.keys.each do |k|
movie[k] = movie[k].gsub(/\"|\[|\]/, '').split(', ') if movie[k]
end
但这似乎只是愚蠢,sinatra应该自动解析它(或不?),或者我可能正在以错误的方式生成表单。 如何解决此问题?
注意:刚尝试生成这样的表单:
- Movie.attribute_names.each do |attr|
- if Movie.serialized_attributes.keys.include? attr
= f.hidden_field attr.to_sym, value: movie.send(attr), multiple: true
- else
= f.hidden_field attr.to_sym, value: movie.send(attr)
答案 0 :(得分:1)
我的建议是避免以数组和散列的形式发送数据。您尝试发送的数据可以很容易地作为一个字符串发送,然后在另一侧进行拆分。例如,为什么不将演员发送为逗号分隔的字符串,然后在收到时发送param["cast_members"].split(/\s*,\s*/)
?某种自动提示是谨慎的,或者你最终会有很多拼写错误的名字。这将通过在发送数据之前用slugs 替换条目来帮助您进一步分隔数据。看看StackOverflow处理标记字段的方式。
如果你真的需要作为数组发送,可以考虑将其转换为JSON,然后在另一端发送和反序列化,而不是自己动手。
答案 1 :(得分:0)
我希望尽可能保持LOC和可读性,因此使用AJAX解决了这个问题:
= link_to 'Save this movie', class: 'button', id: "create_movie_#{movie_id}"
- content_for :scripts do
:javascript
$(function(){
$('#create_movie_#{movie_id}').on('click', function(){
$.post("/movies/create.json",
{movie: #{movie.to_json}},
function(r){
console.log('Response arrived:')
console.log(r)
})
})
})
# controller.rb
post :create, provides: [:html, :json] do
case content_type
when :json
Movie.create(params[:movie]).to_json
when :html
if @movie = Movie.create(params[:movie])
render 'movies/show'
else
redirect 'movies/fetch', error: 'Something went wrong'
end
end
end