文字列に変換された配列からシンボルを抽出しますか?
概要
次の文字列があります。
s = “[:test1, :test2]”
最終的に再びシンボルの配列になるようにしたいと思います。
[:テスト1、:テスト2]
同様の質問が 2 つ見つかりました。
Ruby: ネストされた配列の文字列表現を配列に解析しますか?
Rubyは文字列配列を配列オブジェクトに変換します
ただし、JSON.parse も YAML.load も機能しません。
irb(main):043> test
=> "[:test1, :test2]"
irb(main):044> JSON.parse test
/Users/[...]/.rbenv/versions/3.2.2/lib/ruby/3.2.0/json/common.rb:216:in `parse':
unexpected token at ':test1, :test2]' (JSON::ParserError)
irb(main):045>
irb(main):045> YAML.load test
/Users/[...]/.rbenv/versions/3.2.2/gemsets/rails_test/gems/psych-5.1.1.1/lib/psych/parser.rb:62:in `_native_parse': (<unknown>):
did not find expected node content while parsing a flow node at line 1 column 2 (Psych::SyntaxError)
eval は機能しますが、インジェクションの問題があるため、通常は推奨されません。
irb(main):047> eval(test)
=> [:test1, :test2]
これを行う唯一の方法は基本的な文字列操作ですが、カスタム関数を作成せずに Ruby に組み込まれたより良い方法があるのではないかと考えていました。
irb(main):046> test.delete("[]:").split(", ").map(&:to_sym)
=> [:test1, :test2]
Ruby 3.2.2 を参考にしてください。
解決策
サンプルをクリーンアップすることはできますが、文字列内に格納されたシンボルのフラット配列以外のものに対して動作する保証はありません。
s = "[:test1, :test2]"
s = s.delete(":[]").split(?,).map { _1.strip.to_sym }
=> [:test1, :test2]
ただし、最終的にどのようにしてシンボルの配列ではなく文字列が使用されるのかはまったく不明であり、複合キーに関する Rails ガイドにはどのようにしてその状態になるのかについては説明されていません。フォーム入力または URI パラメーター (どちらも文字列として表されます) からデータを取得し、要素を別の列名として解析していないため、2 つの文字列値から複合キーを適切に形成できると想定せざるを得ません。
フォームの複合キーに関するセクションでは、Rails マジックが機能するにはキーをアンダースコアで区切る必要があると述べています。また、適切にアクセスするにはコントローラーに params.extract_value を実装する必要がある場合もあります。コントローラー、ビュー、モデル コードが示されていないため、間違ったデータのソースに焦点を当てるのではなく、不適切にフォーマットされた最終結果を修正しようとしているように見えます。
たとえそうでなかったとしても、これは最終的には間違った問題を解決することになります。 s に無効な JSON が含まれている理由、または複合キーを適切に形成するために使用できる 2 つの別個のキーを (シンボルではなく) String オブジェクトとして取得していない理由を理解する必要があります。
それらのことを解決します。事後の文字列変更は、原因ではなく症状に対処するものです。