Rails 4: Add Column To An Existing Scaffold - ruby

Yes, this question is flooded on here but most are few years back and I am using Rails 4. I have tried few and it messed up my rails app so I wont take anymore chances.
I have already created a scaffold with fields and I have made many changes to its model, controller and views. Imagine you are working for someone when few weeks later, after you've created a scaffold, they realized they missed out an important column - lol
rails g scaffold Book a:string b:integer
How do I easily add c:date?
Few examples showed running a migration and few says edit the rails console. I am confused with the rails g migration add_this_to_that c:data??
Any reference with your answer is highly appreciated as I'm still learning RoR.

To add new column, you should create migration:
rails g migration add_c_to_books c:date
(note the syntax: add_x_to_y), which will add this file to db/migrate/timestamp_add_c_to_books.rb:
class AddCToBooks < ActiveRecord::Migration
def change
add_column :books, :c, :date
end
end
Now all you need is to run it with:
rake db:migrate
That's it.
You can add multiple columns with:
rails g migration add_c_d_e_to_books c:date d:string e:integer
Which will create following migration:
class AddCDEToBooks < ActiveRecord::Migration
def change
add_column :books, :c, :date
add_column :books, :d, :string
add_column :books, :e, :integer
end
end
Or name it however you want:
rails g migration my_migration
Which will result in clean migration:
class MyMigration < ActiveRecord::Migration
def change
end
end
You are free to specify your directives inside def change.

Related

adding a new table using rails migration..?

I want to add new table using rails migration:
**table_name** users_location_track
**columns** id (primary key, auto increment serial),
user_id (reference to users), location_info (string),
creation_time(time-stamp)
please suggest procedure and code I am new to rails?
In Rails You need to write a command like below:
rails generate migration CreateUserLocationTrack user_id:integer location_info:string
you don't need creation_time as created_at is created by default.
For more information, please follow rails guide.
thank you for criticizing.
Finally I got my answer:
Here's the solution for whoever want in future.
first go to project directory then run following command
rails generate migration add_user_lat_long
and then a migration file will be generate then you can edit in following style:
class AddUserLatLong < ActiveRecord::Migration
def self.up
create_table :users_location_track do |t|
t.string :location_info
t.references :user
t.timestamps
end
add_index :users_location_track, :user_id, :name =>'index_user_lat_longs_on_user_id'
end
def self.down
drop_table :users_location_track
end
end

Rails 3 NoMethodError (undefined method `unserialized_value' for "--- []\n":String):

I am using Rails 3.2.13 and postgress.
I am getting below error only in production server
NoMethodError (undefined method `unserialized_value' for "--- []\n":String):
app/controllers/blogs_controller.rb:159:in `content_generators'
I am serializing Array to store it in db. Below is code.
Controller
class BlogsController < ApplicationController
def content_generators
#blog = Blog.find(params[:id])
#users = #blog.content_generators.map do |id|
User.find(id)
end
end
end
Model
class Blog < ActiveRecord::Base
serialize :post_access, Array
serialize :content_generators, Array
attr_accessible :post_access, :content_generators
end
Migration
class AddContentgeneratorsToBlog < ActiveRecord::Migration
def change
add_column :blogs, :content_generators, :string, :default => [].to_yaml
end
end
I have already used serialization. You can see post_access is serialized. And that works perfect.
But now when I added another column content_generators it starts breaking.
Thanks for your help in advance.
Since you are using postgresql I strongly recommend using the built in array functionality:
# Gemfile
gem 'postgres_ext'
class MyMigration
def change
add_column :my_table, :that_array_column, :text, array: true, default: []
end
end
Then remove the serialize calls in your model and that's it. PG serialized array's behave exactly the same as YAML serialized ones on the model, except the db supports some query methods on them.

Create a migration to add the `admin` field to the `users` table

How to create migration to add the admin field to the users table with a boolean value and set default to false in Sinatra? I am using Active Record.
It's still just ActiveRecord, this would be no different than using it in Rails.
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :admin, :boolean, :default => false
end
end
You may also want to check out the sinatra-activerecord gem which will give you some extra rake tasks and makes things a little easier.
Here is also a useful article on using Sinatra with ActiveRecord.
Sinatra and ActiveRecord
I was having this problem too.
I solved it using change_table method instead of add_column so final code would look like:
class AddAdminToUsers < ActiveRecord::Migration
def change
change_table :users do |t|
t.column :admin, :boolean, default: false
end
end
end

How can I create a field using the id from the same row in ActiveRecord Ruby

-----UPDATE-----
Well, seems that the problem was in last.id. When database is created works OK, but when not fails. Now the question is different: How can I create a field using the id from the same row?
--------ORIGINAL------
I'm working with active record in pure ruby (without Rails), and I'm literally getting crazy with this.
This is my code
class Enviroment < ActiveRecord::Base
#self.table_name = 'enviroments'
self.connection.create_table(:enviroments, :force=>true) do |t|
t.column :name, :string, :default=>'env-'+ (last.id-1).to_s
t.column :ssh, :string, :default=>nil
end
end
and here the error:
ActiveRecord::StatementInvalid: Could not find table 'enviroments'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.2.3/lib/active_record/connection_adapters/sqlite_adapter.rb:465:in `table_structure'
if I useself.table_name = 'enviroments' still not working. I've updated the gems and neither.
I'm newbie with ruby and databases, but I can't understand this problem, I think this same code worked in the past :S
Your code to create the table (very odd to have that in the model by the way) is calling last.id, and of course to call last the table must already exist.
Because you're passing :force => true to create_table you'll actually destroy the table if it already exists.
You could probably make your code work if you stashed the value of last.id in a local variable before the call to create_table but I don't understand why you are creating tables like this.
Finally, this was my solution:
class Enviroment < ActiveRecord::Base
after_create :create_default
private
def create_default
if name == nil
s = 'env-' + self.id.to_s
self.name = s
self.save
end
end
end
class CreateSchema < ActiveRecord::Migration
create_table(:enviroments, :force=>true) do |t|
t.column :name, :string, :default=>nil
t.column :ssh, :string, :default=>nil
end

cant use has_secure_password, password_digest error

Good evening. I have a problem. i am using has_secure_password
and cause of this i have an error undefined methodpassword_digest=' for #`,
but i dont have this method!! Please help, dont know what to do. I read how to fix this problem but it didnt help me(
Here is my User model. Please help if you can.
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
has_secure_password
validates_presence_of :password, :on => :create
before_create { generate_token(:auth_token) }
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
end
You may have forgotten to make sure your migration backing the user model has a column for password_digest. Make sure the column exists and that it's a string. If it doesn't, create a migration to add the column.
Models having has_secure_password store password in password_digest column instead of password column.
In fact password column is not needed.
> u=User.create!(email: 'user#gmail.com', password: '12345678')
> u
#<User:0x007fc794be9278> {
:id => 1,
:email => "user#gmail.com",
:password_digest => "$2a$10$S82GVFR..yO9jihgIoeMj.7dNMWtbCUZpWDKvH0tyMs1SYlfdefmW"
}
I had the same problem, I was following http://www.railstutorial.org/book/modeling_users
and my app/Controllers/users_controllers.rb didn't have a method to create the attribute, I also used git to share the working code between portable laptop for the train and larger home, this created the migration file but didnt apply it, my working user controller is below.
class UsersController < ApplicationController
def new
attr_accessor :name, :email, :password
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
#password = attributes[:password]
end
def formatted_email
"#{#name} <#{#email}>"
end
end
Hey I'm following RoR too and come into the same problem. The trick here is your bundle exec rake db:migrate fails and therefore the password_digest column hasn't been added into the database. My console complains that database for User already exists. I delete the db/development.sqlite3 manully with "SQLite Browser". After running bundle exec rake db:migrate, every test passes

Resources