Reputation: 1108
I am writing a fixture for my table. And a one of the coloums takes in a JSON string as a value.
The problem is the fixture is not loading failing as:
Fixture::FormatError: a YAML error occurred parsing /home/saurajeet/code/dcbox/test/fixtures/hardware.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html
The exact error was:
ArgumentError: syntax error on line 145, col 73: ` portslist: [{"name":"ob1","port_num":0,"port_type":"network"},{"name":"ob2","port_nu'.....
Any solutions to this.
Upvotes: 87
Views: 129988
Reputation: 300
Check out the wonderful interactive documentation and demo provided by yaml-multiline.info. I've archived the text content below:
There are two types of formats that YAML supports for strings: block scalar and flow scalar formats. (Scalars are what YAML calls basic values like numbers or strings, as opposed to complex types like arrays or objects.) Block scalars have more control over how they are interpreted, whereas flow scalars have more limited escaping support.
Block Scalars
A block scalar header has three parts:
Block Style Indicator: The block style indicates how newlines inside the block should behave. If you would like them to be kept as newlines, use the literal style, indicated by a pipe (
|
). If instead you want them to be replaced by spaces, use the folded style, indicated by a right angle bracket (>
). (To get a newline using the folded style, leave a blank line by putting two newlines in. Lines with extra indentation are also not folded.)Block Chomping Indicator: The chomping indicator controls what should happen with newlines at the end of the string. The default, clip, puts a single newline at the end of the string. To remove all newlines, strip them by putting a minus sign (
-
) after the style indicator. Both clip and strip ignore how many newlines are actually at the end of the block; to keep them all put a plus sign (+
) after the style indicator.Indentation Indicator: Ordinarily, the number of spaces you're using to indent a block will be automatically guessed from its first line. You may need a block indentation indicator if the first line of the block starts with extra spaces. In this case, simply put the number of spaces used for indentation (between 1 and 9) at the end of the header.
Flow Scalars
(Ed. reformatted for SO)
Double-quoted
Escapes (like
\n
) work. In addition, newlines can be escaped to prevent them from being converted to a space. Newlines can also be added by leaving a blank line. Leading whitespace on lines is ignored.Single-quoted
Escapes (like
\n
) don't do anything. Newlines can be added by leaving a blank line. Leading whitespace on lines is ignored.Plain
Escapes (like
\n
) don't do anything. Newlines can be added by leaving a blank line. Additional leading whitespace is ignored.
Upvotes: 3
Reputation: 1337
clarkevans' comment on the accepted answer suggested a better answer for long bits of JSON, because you can wrap the lines. I looked up the block scalar syntax he mentioned, and thought I would include an example here:
portslist: >
[{"name":"ob1","port_num":0,"port_type":"network"},
{"name":"ob2","port_nu...
Upvotes: 73
Reputation: 32837
The |
is also possible. For example.
MyObject:
type: object
example: |
{
"id": 54,
"manufacturer": "ACME",
"location": "New York",
"createdAt": "2012-10-01 07:42:35.825565",
"description": "test",
}
Upvotes: 28
Reputation: 109
In my table, the column stripe_connect is of type JSONB . In the fixture, here is what worked. Note that the outer single-quotes are necessary, but square brackets are not. Everything between the single quotes is one long line.
stripe_connect: '{"scope":"read_write", "livemode":false, "token_type":"bearer", "access_token":"sk_test_madeupvalue", "refresh_token":"rt_Ae29madeupvalueyX", "stripe_user_id":"acct_103yZabcdefg", "stripe_publishable_key":"pk_test_0HEOmadeupvalue"}'
Upvotes: 2
Reputation: 1858
For the sake of being complete: In case you're using ActiveRecord::Store
, you can load your data simply using YAML representation of the same data, even if it is a JSON store:
one:
portslist:
-
name: 'ob1'
port_num: 0
port_type: 'network'
-
name: 'ob2'
port_num: 1
port_type: 'network'
Upvotes: 10
Reputation: 281
If you have the string, you can use as simple as Vlad Khomich mentioned:
portslist: '[{"name":"ob1","port_num":0,"port_type":"network"},...]'
If you are using ERB and have an object, you can use to_json and inspect to escape to a JSON string:
portslist: <%= [{name: 'ob1', port_num: 0, port_type: 'network'},...].to_json.inspect %>
And if you have a large JSON specification, you can store it in a separated file and load using Ruby, so you can keep your YAML file clean:
portslist: <%= File.read('/path/to/file.json').inspect %>
Upvotes: 12
Reputation: 5880
I believe taking it into quotes should do the trick:
portslist: '[{"name":"ob1","port_type" ... }]'
Upvotes: 107