0

次のような非表示のフォームがあります。

= 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 に格納されているこの属性ハッシュからレコードを保存しようとすると、データベースでシリアル化エラーが発生します。

{"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)
4

2 に答える 2

1

私のアドバイスは、配列とハッシュの形式でデータを送信することを避けることです。送信しようとしているデータは、1 つの文字列として簡単に送信され、反対側で分割される可能性があります。たとえば、キャスト メンバーをカンマ区切りの文字列として送信し、param["cast_members"].split(/\s*,\s*/)受信時に送信してみませんか? ある種の自動提案は賢明であり、さもなければ、たくさんのスペルミスのある名前になってしまうでしょう。これは、データが送信される前にエントリをスラッグに置き換えることで、データをさらに区切るのに役立ちます。StackOverflow がフィールドのタグ付けを行う方法を見てください。

本当に配列として送信する必要がある場合は、自分で行うのではなく、JSON に変換してから送信し、反対側で逆シリアル化することを検討してください。

于 2013-02-25T16:00:23.863 に答える
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
于 2013-02-25T19:50:38.047 に答える