Storing information inside YAML - ruby-on-rails

I looked through the YAML for ruby documentation and couldn't find an answer.
I have a list of several employees. Each has a name, phone, and email as such:
Employees:
Name | Phone | Email
john 111 a#b.com
joe 123 b#a.org
joan 321 c#a.net
How would I write the above information in YAML to end up with the following ruby output?
employees = [ {:name => 'john', :phone => '111', :email => 'a#b.com'}, {:name => 'joe', :phone => '123', :email => 'b#a.org'}, {:name => 'joan', :phone => '321', :email => 'c#a.net'} ]
This is how I parse the YAML file:
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")
Thank you!

- name: john
phone: 111
email: a#b.com
- name: joe
phone: 123
email: b#a.org
- name: joan
phone: 321
email: c#a.net
Output is string keys, not symbol keys, but you can make that conversion yourself if really necessary.

Note that standard yaml which ships with Ruby 1.8.6 is NOT UTF / Unicode safe.
Use either Ruby 1.9 yaml or Ya2YAML gem if you'll have any non-ASCII test.
Also, the easiest way to see what the yaml input should be is to create (in Ruby irb), an example of your data structure. Then turn it into yaml text by using the .to_yaml object class method.
Eg
require 'yaml'
# create your structure
a = [{'name' => "Larry K", 'age' => 24,
'job' => {'fulltime' => true, 'name' => 'engineer'}}]
a.to_yaml
=> "--- \n- name: Larry K\n job: \n name: engineer\n fulltime: true\n age: 24\n"
# then substitute line breaks for the \n:
---
- name: Larry K
job:
name: engineer
fulltime: true
age: 24

Related

How can I stop rails globalize from falling back to the fallback locale on just one field?

We use the globalize gem and have included Rails.application.config.i18n.fallbacks = [:en] in config/initializers/i18n.rb so that the user sees the English translation of a field if one does not exist in their own language.
That means we see this behavior, as expected:
class Post < ActiveRecord::Base
translates :title, :name
end
puts post.translations.inspect
# => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
#<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
I18n.locale = :en
post.title # => 'Globalize rocks!'
post.name # => 'Globalize'
I18n.locale = :nl
post.title # => ''
post.name # => 'Globalize'
In just one place where we are displaying "posts", the client asked us to not show anything if there is no translation for the "name". Is there a built in way to do this? I.e.:
I18n.locale = :nl
post.title # => ''
post.name_if_translated # => nil
I did find one workaround:
post.name_translations[I18n.locale]
But maybe there's a better way?

Rails 5: How do I point fixtures to other fixtures?

I three models Comment, User and Project. Project and Comment need to point to other objects in order to be valid. For example, a comment needs to point to an author (user) and a project.
The associated fixture files look like this:
# comments.yml
test_comment:
author: users(:test_user)
project: projects(:test_project)
# users.yml
test_user:
name: 'test user'
# projects.yml
test_project:
name: 'Test'
description: 'This is a test'
owner: users(:test_user)
However, I've found that my fixtures are probably set up incorrectly. Rails returns false if I try to save the comment:
assert_equal true, comments(:test_comment)
#=> false
I can see that there are foreign keys for a project and author:
=> #<Comment:0x00007f9b1661f3d8
id: 137725605,
body: "",
project_id: 745075726,
author_id: "31ceee04-5307-5059-91db-0dc2068a780c",
created_at: Fri, 22 Feb 2019 13:17:58 UTC +00:00,
updated_at: Fri, 22 Feb 2019 13:17:58 UTC +00:00>
But when I interrogate them, Rails returns nil.
> comments(:test_comment).author
=> nil
> comments(:test_comment).project
=> nil
I expected that one would return users(:test_user) and the other would return projects(:test_project). I thought perhaps I needed to use ERB in my yaml:
test_comment:
author: <%= users(:test_user) %>
project: <%= projects(:test_project) %>
But that results is a stream of errors when I run my tests:
NoMethodError: undefined method `users' for #<#<Class:0x00007f9b17692ff8>:0x00007f9b17692dc8>
What do I need to do to point fixtures to other fixtures? Can it be done? What have I done wrong?
In the Rails guide on Testing with YAML fixtures, you can see that you don't need users(:test_user) to refer to some other object. Instead, you can simply write test_user:
# comments.yml
test_comment:
author: test_user
project: test_project
# users.yml
test_user:
name: 'test user'
# projects.yml
test_project:
name: 'Test'
description: 'This is a test'
owner: test_user
Hope this helps!

Mongoid in rails not saving document

I'm using rails 4.2.5 with mongoid 5.1.0 on windows 10 in dev mode. I have created a model "Signup" but it won't save to MongoDB. I can see that rails connects to MongoDB but no transactions are performned.
What am I missing?
Model code:
class Signup
include Mongoid::Document
field :email, type: String
field :date, type: DateTime, default: ->{ Time.now }
end
Console tests:
irb(main):034:0> s = Signup.create
=> #<Signup _id: 57b9d0436fc5511c04a945ce, email: nil, date: 2016-08-21 16:01:07 UTC>
irb(main):035:0> Signup.count
=> 0
irb(main):036:0> s.save!
=> true
irb(main):037:0> Signup.count
=> 0
irb(main):038:0>
found the solution, I used a dot in the database name in mongoid.yml (project.io) which somehow hindered db creation. I removed it (project_io) and everything is working now as it should.

Rails 4 - nil value on rake db:seed [duplicate]

I have a CarrierWave rails uploader. I want to seed the database with fake users so I'm trying to add the images in with the same seed file. The images are in a common storage, so if I can just get the avatar strings in the database they'll work. When it saves the users though the image's aren't sticking.
# db/seeds.rb
user1 = User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :avatar => "v1357014344/bdylan.jpg"
user1.save
# IRB
User.first
=> #<User id: 1, email: "test1#test.com", name: "Bob Dylan", avatar: nil>
> a = User.first
> a.avatar = "v1357014344/bdylan.jpg"
> a.save
(10.7ms) commit transaction
=> true
> a
=> #<User id: 1, email: "test1#test.com", name: "Bob Dylan", avatar: nil>
You will have to insert the data in the following way.
File.open(File.join(Rails.root, 'test.jpg'))
So the entire user create would look like
User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :avatar => open("v1357014344/bdylan.jpg")
Related question
Besides using open() as Nishant suggestions, you can also specify remote_avatar_url to manually set the remote URL.
User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :remote_avatar_url => "http://upload.wikimedia.org/wikipedia/commons/2/28/Joan_Baez_Bob_Dylan_crop.jpg"
Thanks to JosephJaber for suggesting this in Seeding file uploads with CarrierWave, Rails 3
I used this approach to populate some video URLs for CarrierWave Uploader in my seeds.rb
To update the database directly and skip out on CarrierWave:
model[:attribute] = 'url.jpg'
model.save

Override Rails Uploader to seed database

I have a CarrierWave rails uploader. I want to seed the database with fake users so I'm trying to add the images in with the same seed file. The images are in a common storage, so if I can just get the avatar strings in the database they'll work. When it saves the users though the image's aren't sticking.
# db/seeds.rb
user1 = User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :avatar => "v1357014344/bdylan.jpg"
user1.save
# IRB
User.first
=> #<User id: 1, email: "test1#test.com", name: "Bob Dylan", avatar: nil>
> a = User.first
> a.avatar = "v1357014344/bdylan.jpg"
> a.save
(10.7ms) commit transaction
=> true
> a
=> #<User id: 1, email: "test1#test.com", name: "Bob Dylan", avatar: nil>
You will have to insert the data in the following way.
File.open(File.join(Rails.root, 'test.jpg'))
So the entire user create would look like
User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :avatar => open("v1357014344/bdylan.jpg")
Related question
Besides using open() as Nishant suggestions, you can also specify remote_avatar_url to manually set the remote URL.
User.create :email => "test1#test.com", :password => "testing", :name => "Bob Dylan", :remote_avatar_url => "http://upload.wikimedia.org/wikipedia/commons/2/28/Joan_Baez_Bob_Dylan_crop.jpg"
Thanks to JosephJaber for suggesting this in Seeding file uploads with CarrierWave, Rails 3
I used this approach to populate some video URLs for CarrierWave Uploader in my seeds.rb
To update the database directly and skip out on CarrierWave:
model[:attribute] = 'url.jpg'
model.save

Resources