adding a new table using rails migration..? - rails-migrations

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

Related

Rails 4: Add Column To An Existing Scaffold

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.

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

Rails model singular format

This is more a question to see if an error has occurred when creating a model in my app.
I have created a model in the usual way
rails g model Media
Now i thought that this would actually create the following
class CreateMedias < ActiveRecord::Migration
def change
create_table :medias do |t|
t.timestamps
end
end
end
but it didnt it created
class CreateMedia < ActiveRecord::Migration
def change
create_table :media do |t|
t.timestamps
end
end
end
I thought the model represented as single media but the database consists of many medias. Why would the migration not change to medias? Is it best to delete this model and try it again or is this normal behaviour?
Thanks
Media is the plural of Medium.
The clean way would be to have a Medium model and Media for table name.
Media as data type is not countable. So you could add inflections.
Just put further code into your config/initializers/inflection.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.uncountable 'media'
end
see docks here

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

(Object doesn't support #inspect)

I have a simple case, involving two model classes:
class Game < ActiveRecord::Base
has_many :snapshots
def initialize(params={})
# ...
end
end
class Snapshot < ActiveRecord::Base
belongs_to :game
def initialize(params={})
# ...
end
end
with these migrations:
class CreateGames < ActiveRecord::Migration
def change
create_table :games do |t|
t.string :name
t.string :difficulty
t.string :status
t.timestamps
end
end
end
class CreateSnapshots < ActiveRecord::Migration
def change
create_table :snapshots do |t|
t.integer :game_id
t.integer :branch_mark
t.string :previous_state
t.integer :new_row
t.integer :new_column
t.integer :new_value
t.timestamps
end
end
end
If I attempt to create a Snapshot instance in rails console, using
Snapshot.new
I get
(Object doesn't support #inspect)
Now for the good part. If I comment out the initialize method in snapshot.rb, then Snapshot.new works. Why is this happening?
BTW I am using Rails 3.1, and Ruby 1.9.2
This is happening because you override the initialize method of your base class (ActiveRecord::Base). Instance variables defined in your base class will not get initialized and #inspect will fail.
To fix this problem you need to call super in your sub class:
class Game < ActiveRecord::Base
has_many :snapshots
def initialize(params={})
super(params)
# ...
end
end
I had this symptom when I had a serialize in a model like this;
serialize :column1, :column2
Needs to be like;
serialize :column1
serialize :column2
I ran into this issue when I used an invalid association name in a joins.
For example,
Book.joins(:authors).first
Should be
Book.joins(:author).first
Assuming a Book model belongs_to an Author model.
This can also happen when you implement after_initialize, particularly if you are attempting to access attributes which were not included in your select. For instance:
after_initialize do |pet|
pet.speak_method ||= bark # default
end
To fix, add a test for whether the attribute exists:
after_initialize do |pet|
pet.speak_method ||= bark if pet.attributes.include? 'speak_method' # default`
end
I'm not sure exactly why, but I got this error when I accidentally misspelled 'belongs_to' as 'belong_to' in the associated class definition.
I believe you forgot to
rails db:migrate
Try calling .valid? on the new object to see if you can get a more helpful error.
In my case, I got this error from a block of code that creates a new instance of one of my models and assigns values to its fields. It turns out that my code was assigning a value to one of the fields that Rails couldn't match with that field's type. Calling valid? on the new object gave me a more helpful error (undefined method `to_f' for #<MatchData...).
I ran into this problem after trying to integrate devise authentication with an existing User model, I solved it by running command below:
$spring stop
Don't know the exact cause but hope it helps someone.
This is a misleading and nonspecific error. For instance, I just got it because I made a scope like this:
scope :posted, -> { where('posted_on_date <= ?', Date.today) }
when it should have been:
scope :posted, -> { where('post_on_date <= ?', Date.today) }
In my case, this was due to my mistakenly using the posted_on_date attribute.
I get this problem if the model contains an after_find.
The same error if you put the attribute type wrong:
attribute :publicar, :integer, default: true
instead of
attribute :publicar, :boolean, default: true
I was getting this error when running an ActiveRecord .where clause/method.
It was simply because there was a typo in the column name. Once I fixed the typo the query worked exactly as expected.
Wrong:
Package.where(scrape_nunber: 2)
Right (fixed typo in column name, and it works now):
Package.where(scrape_number: 2)
Just double check there isn't a typo in your column name(s) in the where clause.

Resources