Saurajeet
Saurajeet

Reputation: 1108

Embedding JSON Data into YAML file

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

Answers (7)

evan.bovie
evan.bovie

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

Paul Lynch
Paul Lynch

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

H6_
H6_

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

Norm
Norm

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

murb
murb

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

Renato Silva Das Neves
Renato Silva Das Neves

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

Vlad Khomich
Vlad Khomich

Reputation: 5880

I believe taking it into quotes should do the trick:

portslist: '[{"name":"ob1","port_type" ... }]'

Upvotes: 107

Related Questions