Splitting User and Profile issue - ruby-on-rails-4

I'm probably missing something trivial...
I have a User model that 'has_one' UserProfile:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
before_create :create_remember_token
has_many :user_roles, dependent: :destroy
has_many :roles, through: :user_roles
has_one :user_profile, dependent: :destroy
accepts_nested_attributes_for :user_roles, :user_profile, allow_destroy: true
validates :email, presence: true, format: {with: TextUtils::VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
has_secure_password
validates :password, length: { minimum: 6 }
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
def admin?
in_role?(Role::ADMINISTRATOR)
end
def in_role?(role)
!self.roles.find_by_name(role).nil?
end
private
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
end
and I have a UserProfile model that 'belongs_to' User:
class UserProfile < ActiveRecord::Base
belongs_to :user
has_one :address, dependent: :destroy
accepts_nested_attributes_for :address
validates :first, :last, :ssn, :title, :division, :phone_home, :phone_mobile, :phone_work, :phone_work_ext,
:emergency_phone, :emergency_name, :emergency_relation, presence: true
validates :personal_email, format: { with: TextUtils::VALID_EMAIL_REGEX }
end
When I try to seed the database as such (or any other way where profile is assigned to user):
# Admin
admin = User.create!(email: "admin#work.com", password: "secret", password_confirmation: "secret",
user_profile: UserProfile.new(
first: "Admin",
last: "User",
address_attributes: {line1: "123 Fake Street", line2: "Suite 1", city: "Some City", state: "FL", zip_code: "11111"},
ssn: "123-45-6789",
phone_work: "(111) 222-3333",
phone_work_ext: "110",
personal_email: "test#home.com")
)
I keep getting the following error:
rake aborted!
ActiveRecord::UnknownAttributeError: unknown attribute: user_profile_id
C:/work/Portal/db/seeds.rb:12:in `'
Tasks: TOP => db:seed
(See full trace by running task with --trace)
I'm at a loss as to why this is happening. Any help will be appreciated! I am using Rails 4.1.4, if that matters.

Everything has to be passed as (nested) hash(es):
admin = User.create!({
email: "admin#work.com",
password: "secret",
password_confirmation: "secret",
user_profile_attributes: {
first: "Admin",
last: "User",
address_attributes: {
line1: "123 Fake Street",
line2: "Suite 1",
city: "Some City",
state: "FL",
zip_code: "11111"
},
ssn: "123-45-6789",
phone_work: "(111) 222-3333",
phone_work_ext: "110",
personal_email: "test#home.com"
}
})
Update
Working example:
$ rails new testapplication
create
create README.rdoc
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
create app/assets/javascripts/application.js
create app/assets/stylesheets/application.css
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/views/layouts/application.html.erb
create app/assets/images/.keep
create app/mailers/.keep
create app/models/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/bundle
create bin/rails
create bin/rake
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/secrets.yml
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/backtrace_silencers.rb
create config/initializers/cookies_serializer.rb
create config/initializers/filter_parameter_logging.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/session_store.rb
create config/initializers/wrap_parameters.rb
create config/locales
create config/locales/en.yml
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create lib
create lib/tasks
create lib/tasks/.keep
create lib/assets
create lib/assets/.keep
create log
create log/.keep
create public
create public/404.html
create public/422.html
create public/500.html
create public/favicon.ico
create public/robots.txt
create test/fixtures
create test/fixtures/.keep
create test/controllers
create test/controllers/.keep
create test/mailers
create test/mailers/.keep
create test/models
create test/models/.keep
create test/helpers
create test/helpers/.keep
create test/integration
create test/integration/.keep
create test/test_helper.rb
create tmp/cache
create tmp/cache/assets
create vendor/assets/javascripts
create vendor/assets/javascripts/.keep
create vendor/assets/stylesheets
create vendor/assets/stylesheets/.keep
run bundle install
Your user account isn't allowed to install to the system Rubygems.
You can cancel this installation and run:
bundle install --path vendor/bundle
to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to Rubygems using sudo.
$ cd testapplication/
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Installing rake 10.3.2
Installing i18n 0.6.11
Using json 1.8.1
Installing minitest 5.4.1
Installing thread_safe 0.3.4
Installing tzinfo 1.2.2
Installing activesupport 4.1.1
Installing builder 3.2.2
Installing erubis 2.7.0
Installing actionview 4.1.1
Installing rack 1.5.2
Installing rack-test 0.6.2
Installing actionpack 4.1.1
Installing mime-types 1.25.1
Installing polyglot 0.3.5
Installing treetop 1.4.15
Installing mail 2.5.4
Installing actionmailer 4.1.1
Installing activemodel 4.1.1
Installing arel 5.0.1.20140414130214
Installing activerecord 4.1.1
Using bundler 1.6.1
Installing coffee-script-source 1.8.0
Installing execjs 2.2.1
Installing coffee-script 2.3.0
Installing thor 0.19.1
Installing railties 4.1.1
Installing coffee-rails 4.0.1
Installing hike 1.2.3
Installing multi_json 1.10.1
Installing jbuilder 2.1.3
Installing jquery-rails 3.1.1
Installing tilt 1.4.1
Installing sprockets 2.11.0
Installing sprockets-rails 2.1.3
Installing rails 4.1.1
Installing rdoc 4.1.1
Installing sass 3.2.19
Installing sass-rails 4.0.3
Installing sdoc 0.4.1
Installing spring 1.1.3
Installing sqlite3 1.3.9
Installing turbolinks 2.3.0
Installing uglifier 2.5.3
Your bundle is complete!
It was installed into ./vendor/bundle
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:
<= 1.8.6 : unsupported
= 1.8.7 : gem install rdoc-data; rdoc-data --install
= 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!
$ ./bin/rails g model user
invoke active_record
create db/migrate/20140829201904_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
$ ./bin/rails g model user_profile user:references test:integer
invoke active_record
create db/migrate/20140829201916_create_user_profiles.rb
create app/models/user_profile.rb
invoke test_unit
create test/models/user_profile_test.rb
create test/fixtures/user_profiles.yml
$ ./bin/rake db:migrate
== 20140829201904 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0012s
== 20140829201904 CreateUsers: migrated (0.0013s) =============================
== 20140829201916 CreateUserProfiles: migrating ===============================
-- create_table(:user_profiles)
-> 0.0010s
== 20140829201916 CreateUserProfiles: migrated (0.0010s) ======================
Then edited the user model:
class User < ActiveRecord::Base
has_one :user_profile
accepts_nested_attributes_for :user_profile
end
UserProfile is already correct:
class UserProfile < ActiveRecord::Base
belongs_to :user
end
and run the create statement:
$ ./bin/rails c
Loading development environment (Rails 4.1.1)
2.1.0 :001 > User.create({user_profile_attributes: {test: 5}})
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2014-08-29 20:21:41.860036"], ["updated_at", "2014-08-29 20:21:41.860036"]]
SQL (0.4ms) INSERT INTO "user_profiles" ("created_at", "test", "updated_at", "user_id") VALUES (?, ?, ?, ?) [["created_at", "2014-08-29 20:21:41.864624"], ["test", 5], ["updated_at", "2014-08-29 20:21:41.864624"], ["user_id", 1]]
(1.3ms) commit transaction
=> #<User id: 1, created_at: "2014-08-29 20:21:41", updated_at: "2014-08-29 20:21:41">
2.1.0 :002 > User.last.user_profile.inspect
User Load (0.3ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
UserProfile Load (0.3ms) SELECT "user_profiles".* FROM "user_profiles" WHERE "user_profiles"."user_id" = ? LIMIT 1 [["user_id", 1]]
=> "#<UserProfile id: 1, user_id: 1, test: 5, created_at: \"2014-08-29 20:21:41\", updated_at: \"2014-08-29 20:21:41\">"

Related

CarrierWave url nil after upgrading from Rails 3 to Rails 4

While upgrading our app from Rails 3.2.22 to Rails 4.2.11, several CarrierWave methods that worked prior to the upgrade now return nil, such as .url and .file. We are hosting our assets on AWS S3 and our app is hosted on Heroku. Strangely, the images work as expected in our dev environment.
CarrierWave 1.3.1 (upgraded from 0.11.2)
Rails 4.2.11, upgraded from 3.2.22
Ruby 2.2.5
fog-aws 3.3.0
So far I have tried changing around the carrierwave config, and playing around with different methods in the rails console and comparing the results in development with production.
Gemfile
source 'https://rubygems.org'
ruby '2.2.5'
gem 'rails', '4.2.11'
gem 'puma'
gem 'pg', '0.15.1'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'rack-cors'
gem 'sprockets_uglifier_with_source_maps'
gem 'carrierwave'
gem 'mini_magick', '3.6.0'
gem 'paper_trail', '>= 4.0'
gem 'fog-aws'
gem 'aws-sdk-s3', '~> 1'
gem 'identity_cache', '>= 0.2'
gem 'memcachier'
gem 'dalli'
gem 'connection_pool'
gem 'active_model_serializers', '>= 0.10'
gem 'formtastic', '~> 3.1.0'
gem 'sprockets-rails', require: 'sprockets/railtie'
gem 'sprockets-image_compressor'
gem 'actionpack-action_caching'
gem 'sass-rails', '5.0.6'
gem 'uglifier', '2.5.0'
gem 'compass-rails'
gem 'sprite-factory', '1.5.3'
gem 'responders', '~> 2.0'
group :development do
gem 'rack-mini-profiler'
gem 'rmagick', '2.13.2'
end
carrierwave.rb
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: ENV['FOG_PROVIDER'],
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
region: ENV['FOG_REGION'],
endpoint: ENV['FOG_HOST']
}
if Rails.env.production?
config.storage = :fog
config.fog_directory = ENV['FOG_DIRECTORY']
config.fog_public = false
config.fog_authenticated_url_expiration = 1800
else
config.asset_host = "#{ENV['FOG_HOST']}"
config.storage = :file
config.enable_processing = false if Rails.env.test?
end
end
art_uploader.rb
# encoding: utf-8
class ArtUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
version :thumbnail do
process resize_to_fill: [100, 100]
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Add a white list of extensions which are allowed to be uploaded.
def extension_white_list
%w(jpg jpeg png)
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
if model.has_fallback_art?
version_name == :thumbnail
model.song.artist.photo.small_thumb.url :
model.song.artist.photo.album_art.url
end
end
end
I expect to be able to return the asset path from S3 when I enter
art.url
In development I get art.url => "https://qa-marmosetmusic-com.s3.amazonaws.com/uploads/artist/photo/173/af2ac015-1d44-4481-b5d6-5bf5cb8c0e23.jpg"
However in prodution art.url => nil.
When I enter art in the development console, it returns this object:
=> #<ArtUploader::Uploader70128841541160:0x007f904c7c88f8
#cache_id=nil,
#file=
#<CarrierWave::SanitizedFile:0x007f904c1ffd68
#content=nil,
#content_type=nil,
#file=
"/Users/ekingan/dev/marmoset/public/uploads/album/art/3540/thumbnail_Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
#original_filename=nil>,
#filename=nil,
#format=nil,
#model=
#<Album:0x007f904a0417a8
id: 3540,
title: "Your Heart",
art: "Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
state: "active",
description: "",
created_at: Tue, 27 Nov 2018 12:50:14 PST -08:00,
updated_at: Tue, 27 Nov 2018 12:50:14 PST -08:00>,
#mounted_as=:art,
#parent_version=
#<ArtUploader:0x007f904c7c9618
#cache_id=nil,
#file=
#<CarrierWave::SanitizedFile:0x007f904c7c8948
#content=nil,
#content_type=nil,
#file="/Users/ekingan/dev/marmoset/public/uploads/album/art/3540/Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
#original_filename=nil>,
#filename=nil,
#format=nil,
#model=
#<Album:0x007f904a0417a8
id: 3540,
title: "Your Heart",
art: "Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
state: "active",
description: "",
created_at: Tue, 27 Nov 2018 12:50:14 PST -08:00,
updated_at: Tue, 27 Nov 2018 12:50:14 PST -08:00>,
#mounted_as=:art,
#storage=#<CarrierWave::Storage::File:0x007f904c7c9118 #cache_called=nil, #uploader=#<ArtUploader:0x007f904c7c9618 ...>>,
#versions={:thumbnail=>#<ArtUploader::Uploader70128841541160:0x007f904c7c88f8 ...>}>,
#storage=
#<CarrierWave::Storage::File:0x007f904c7c86f0
#cache_called=nil,
#uploader=#<ArtUploader::Uploader70128841541160:0x007f904c7c88f8 ...>>,
#versions={}>
When I enter the same in production it returns:
#<ArtUploader::Uploader6168740:0x000000072781c8 #model=#<Album id: 2008, title: "Vektlaus", art: "Daniel+Kvammen+-+Vektlaus.jpg", state: "active", description: nil, created_at: "2017-05-19 18:40:43", updated_at: "2017-07-26 16:51:17">, #mounted_as=:art, #file=nil, #filename=nil, #cache_id=nil, #versions={}, #format=nil, #parent_version=#<ArtUploader:0x00000007278d30 #model=#<Album id: 2008, title: "Vektlaus", art: "Daniel+Kvammen+-+Vektlaus.jpg", state: "active", description: nil, created_at: "2017-05-19 18:40:43", updated_at: "2017-07-26 16:51:17">, #mounted_as=:art, #file=nil, #filename=nil, #cache_id=nil, #versions={:thumbnail=>#<ArtUploader::Uploader6168740:0x000000072781c8 ...>}, #format=nil, #storage=#<CarrierWave::Storage::Fog:0x000000072786f0 #uploader=#<ArtUploader:0x00000007278d30 ...>>>, #storage=#<CarrierWave::Storage::Fog:0x00000007267300 #uploader=#<ArtUploader::Uploader6168740:0x000000072781c8 ...>>>
I would love to hear any suggestions.
Thanks!
We resolved this!
We had a file in carrierwave/storage called fog.rb that was overriding the gem behavior and causing this issue. Removing that file allowed everything to work as intended.

Integrating letter_opener with Devise

I am currently using the Devise gem for authentication with my rails app and I am having trouble using the letter_opener gem with it. I can get it to work with a the standard mailer but I'm not sure how to configure the Devise mailer to work with letter_opener.
How do I configure letter_opener so that it will work with the emails sent with Devise?
Don`t know how it was in Rails 4.x but in Rails 5.1 I did it like so:
1) Install
gem 'letter_opener_web', group: :development
2) Make your devise model
confirmable
here`s the link https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users
3) Add this config
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_mailer.delivery_method = :letter_opener
to
config/environments/development.rb
in your devise initializer(config/initializers/devise.rb)
config.mailer_sender = 'foo#bar.com'
config.mailer = Devise.mailer
4) Do not forget to mount your letter_opener web interface to routes.rb
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
This works pretty nice. Your mails will be available at
localhost:3000/letter_opener

rake db:migrate fails with globalize gem and rails 4.1.7

I'm trying to use the globalize gem with Rails 4.1.7.
Using latest RVM version, os is Ubuntu 12.04, db is postgresql 9.3.
Following the instructions found in readme.md on github i added the translates directive in my model and scaffolded a migration
class Ingredient < ActiveRecord::Base
translates :name, :description
end
class CreateIngredientTranslations < ActiveRecord::Migration
def up
Ingredient.create.translation_table!({
name: :string,
descripion: :text
}, {
migrate_data: true
})
end
def down
Ingredient.drop_translation_table! migrate_data: true
end
end
Then when i do rake db:migrate i get the following error
PG::UndefinedTable: ERROR: relation "ingredient_translations" does not exsist
LINE 5: WHERE a.attrelid = '"ingredient_translations"...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"ingredient_translations"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
/home/kranz/.rvm/gems/ruby-2.1.4#recipes/gems/activerecord-4.1.7/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `async_exec'
This is really weird.
Googling around for this kind of error I found a ticket in github
https://github.com/globalize/globalize/issues/288
opened in Dec 2013 and still not closed which seems very similar; the only solution seems to be a hack in globalize code, but i'd prefer not to monkey patching code at that level.
Is it due to the combination of postgres and globalize or there is any other solution to this?

(Rails) : NoMethodError: undefined method cost' for BCrypt::Engine:Class

When I learn "Ruby on Rails Tutorial", and I want to create a User on console:
irb(main):001:0> User.create(name:"gsky",email:"k#q.com",
irb(main):002:1* password:"aaaaaa",password_confirmation:"aaaaaa")
then, I getting the following error message:
NoMethodError: undefined method cost' for BCrypt::Engine:Class
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.
0.2/lib/active_model/secure_password.rb:104:inpassword='
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4
.0.2/lib/active_record/attribute_assignment.rb:42:in public_send'
This is user model:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
Add bcrypt-ruby to your Gemfile as specified below:
gem 'bcrypt-ruby', '3.1.2'
then run bundle update from your project root directory and bundle install
When i saw "Ruby On Rails Tutorial" I have met the same problem,
I solved it by set Gemfile from:
gem 'bcrypt-ruby', '3.0.1'
to:
gem 'bcrypt-ruby', '3.1.2'
then run:
bundle install
Also going for the tutorial/book and having the same problems, I used gem 'bcrypt-ruby', '~> 3.0.0' because of problems with bundle install. After going through secure_password.rb, the problem was in BCrypt::Engine.cost, this method actually doesn't exist.
I changed my gem to gem 'bcrypt-ruby', '~> 3.1.0' which installed bcrypt 3.1.7. Saw a warning message about the gem being renamed and changed it to gem 'bcrypt', '~> 3.1.0' (this part shouldn't matter). After doing bundle install, I was able to see the implementation of Bcrypt::Engine.cost through my IDE and I was able to make my user in rails c.
I want to add that adding ActiveModel::SecurePassword.min_cost = true in test.rb was able to let me make new users if I ran rails c in test environment, but when I added the same line in development.rb, it didn't work.
I think you are learning rails from the tutorial. If you just want to continue and not spent much time on doing the right fix, you can just use the cost as say 10, instead of calling the BCrypt::Engine.cost method.
So replace
cost = BCrypt::Engine.cost
with
cost = 10
This value when used will take less than 200ms to compute and that should be okay.
Tested on mac:
Include this in your gemfile:
gem 'bcrypt', '3.1.11'
run:
xcode-select --install
then run: bundle install
That's it.
Best of lucks

How do I get my rails app to use my postgresql db?

I installed prostgres to use with my rails4 app, and I am able to connect to the database server and create databases. Then I made the necessary changes to my Gemfile and config/database.yml to use postgres. Then I created a new app, and in the app I created a User model:
$ rails generate model User name:string email:string
invoke active_record
create db/migrate/20130806145935_create_users.rb
create app/models/user.rb
invoke rspec
create spec/models/user_spec.rb
And then I did:
$ bundle exec rake db:migrate
== CreateUsers: migrating ====================================================
-- create_table(:users)
-> 0.1498s
== CreateUsers: migrated (0.1500s) ===========================================
But in the db directory, I see these files:
development.sqlite3
test.sqlite3
Furthermore, when I try to look at those files with the SQLite Database Browser, I get an error that says they are not sqlite 3 databases. In fact, they are empty:
~/rails_projects/sample_app4_0/db$ ls -al
total 40
drwxr-xr-x 8 7stud staff 272 Aug 6 22:50 .
drwxr-xr-x 24 7stud staff 816 Aug 6 22:23 ..
-rw-r--r-- 1 7stud staff 0 Jul 30 00:21 development.sqlite3
drwxr-xr-x 3 7stud staff 102 Aug 6 22:22 migrate
-rw-r--r-- 1 7stud staff 1063 Aug 6 09:06 schema.rb
-rw-r--r-- 1 7stud staff 343 Jul 29 20:01 seeds.rb
-rw-r--r-- 1 7stud staff 0 Jul 30 03:02 test.sqlite3
I read that you can create your rails app with a flag that tells it to use postgres:
rails new myapp --database postgresql
but I already created my app. Do I have to start over? I'm using git if that makes a difference.
My Gemfile:
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0
gem 'rails', '4.0.0'
gem 'bootstrap-sass', '2.3.2.0'
#Added for postgres:
gem 'pg', '0.15.1'
group :development, :test do
#gem 'sqlite3', '1.3.7'
gem 'rspec-rails', '2.13.1'
gem 'guard-rspec', '2.5.0'
gem 'spork-rails', github: 'sporkrb/spork-rails'
gem 'guard-spork', '1.5.0'
gem 'childprocess', '0.3.6'
end
group :test do
gem 'selenium-webdriver', '2.0.0'
gem 'capybara', '2.1.0'
gem 'growl', '1.0.3'
end
gem 'sass-rails', '4.0.0'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.0'
gem 'jquery-rails', '2.2.1'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'
group :doc do
gem 'sdoc', '0.3.20', require: false
end
group :production do
#gem 'pg', '0.15.1'
gem 'rails_12factor', '0.0.2'
end
config/database.yml:
development:
adapter: postgresql
encoding: utf8
database: sampleapp_dev #can be anything unique
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: postgresql
encoding: utf8
database: sampleapp_test #can be anything unique
pool: 5
timeout: 5000
production:
adapter: postgresql
database: sampleapp_prod
pool: 5
timeout: 5000
Okay, to figure out what's going on I created a new test app using the --database flag:
rails_projects$ rails new test_postgres --database postgresql
It turns out, all that does is set up your config/database.yml file like this:
development:
adapter: postgresql
encoding: unicode
database: test_postgres_development
pool: 5
username: test_postgres
password:
test:
adapter: postgresql
encoding: unicode
database: test_postgres_test
pool: 5
username: test_postgres
password:
production:
adapter: postgresql
encoding: unicode
database: test_postgres_production
pool: 5
username: test_postgres
password:
And the empty sqlite files:
development.sqlite3
test.sqlite3
were still present in the db directory.
Then I started up postgres, and I used pgAdmin3 to connect to the postgres database server. (If that is confusing, see: How do I start enterpiseDB PostgreSQL on Mac OSX 10.6.8?)
Then I created a model:
~/rails_projects$ cd test_postgres/
~/rails_projects/test_postgres$ rails g scaffold Post title:string author:string body:text
invoke active_record
create db/migrate/20130807061320_create_posts.rb
create app/models/post.rb
invoke test_unit
create test/models/post_test.rb
create test/fixtures/posts.yml
invoke resource_route
route resources :posts
invoke scaffold_controller
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
create app/views/posts/index.html.erb
create app/views/posts/edit.html.erb
create app/views/posts/show.html.erb
create app/views/posts/new.html.erb
create app/views/posts/_form.html.erb
invoke test_unit
create test/controllers/posts_controller_test.rb
invoke helper
create app/helpers/posts_helper.rb
invoke test_unit
create test/helpers/posts_helper_test.rb
invoke jbuilder
create app/views/posts/index.json.jbuilder
create app/views/posts/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/posts.js.coffee
invoke scss
create app/assets/stylesheets/posts.css.scss
invoke scss
create app/assets/stylesheets/scaffolds.css.scss
Then I tried to execute the migration:
~/rails_projects/test_postgres$ bundle exec rake db:migrate
rake aborted!
FATAL: role "test_postgres" does not exist
...
...
That error occured because I don't have a database user(or role in postgres speak) named test_postgres--and it's likely no one else will either. When I set up postgres, I created the user 7stud, which is my Mac user name. To fix that rails error, I just changed the username to 7stud on the three lines in config/database.yml. Edit: in fact, I didn't even need to do that. Because I am the user 7stud on my Mac, that means I am executing my rails commands as 7stud, and coupled with the fact that my postgres db was setup with a user named 7stud, that allows me to completely eliminate the username line in config/database.yml:
development:
adapter: postgresql
encoding: unicode
database: test_postgres_development
pool: 5
test:
adapter: postgresql
encoding: unicode
database: test_postgres_test
pool: 5
production:
adapter: postgresql
encoding: unicode
database: test_postgres_production
pool: 5
Then I tried executing the migration again:
~/rails_projects/test_postgres$ bundle exec rake db:migrate
rake aborted!
FATAL: database "test_postgres_development" does not exist
...
...
Notice that the database.yml file specifies three database names. So I created the development and test databases:
~$ cd /Library/PostgreSQL/9.2/
/Library/PostgreSQL/9.2$ sudo su postgres
Password: <normal sudo password>
bash-3.2$ createdb -O7stud -Eutf8 test_postgres_development
bash-3.2$ createdb -O7stud -Eutf8 test_postgres_test
-O owner
-E encoding
Then I tried executing the migration again:
~/rails_projects/test_postgres$ bundle exec rake db:migrate
== CreatePosts: migrating ====================================================
-- create_table(:posts)
-> 0.0441s
== CreatePosts: migrated (0.0443s) ===========================================
Success (but elsewhere on the net examples show different output with 'Notice' lines).
Then I started a server:
~/rails_projects/test_postgres$ rails s
...and in my browser I entered the url:
http://localhost:3000/posts
...and I created a couple of Posts.
Then using pgAdmin3, I tried to find the posts in the test_postgres_development database. First, I refreshed the 'Databases(3)' line in pgAdmin3 by right clicking on the line and choosing 'Refresh'. Then I searched through the test_postgres_development directory for a long time, with no luck. Under Schemas, I could see a Tables directory that contained a posts directory, so the table got created, but I couldn't figure out how to see if there were any entries in the table. It turns out, you have to right click on the posts directory, then select 'View Data', and voila there were the posts I created.
Or you can view the entries using the command line:
~$ cd /Library/PostgreSQL/9.2/
/Library/PostgreSQL/9.2$ sudo su postgres
Password: <normal sudo password>
bash-3.2$ psql -U 7stud test_postgres_development
psql (9.2.4)
Type "help" for help.
test_postgres_development=> \dt
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+-------
public | posts | table | 7stud
public | schema_migrations | table | 7stud
(2 rows)
test_postgres_development=> \d posts
Table "public.posts"
Column | Type | Modifiers
------------+-----------------------------+----------------------------------------------------
id | integer | not null default nextval('posts_id_seq'::regclass)
title | character varying(255) |
author | character varying(255) |
body | text |
created_at | timestamp without time zone |
updated_at | timestamp without time zone |
Indexes:
"posts_pkey" PRIMARY KEY, btree (id)
test_postgres_development=> select id, title, author, created_at from posts;
id | title | author | created_at
----+------------------------+--------------+----------------------------
1 | Hi there. | Tom | 2013-08-07 06:24:57.806237
2 | Ola! | Nancy | 2013-08-07 06:25:23.989643
(2 rows)
test_postgres_development=>