I am a beginner in Rails. In the following code,there is an id which is set as false. What's the meaning of it?
class CreateCoursesStudents < ActiveRecord::Migration
def self.up
create_table :courses_students, **:id => false** do |t|
t.integer :course_id,:null => false
t.integer :student_id, :null => false
end
# Add index to speed up looking up the connection, and ensure # we only
enrol a student into each course once
add_index :courses_students, [:course_id, :student_id], :unique => true
end
def self.down
remove_index :courses_students, :column => [:course_id, :student_id]
drop_table :courses_students
end
end
Thanks
:id => false defines a table with no primary key, which is useful e.g. when you create a join table for a many-to-many relationship.
:null=>false indicates that the field in question cannot be null for any row that gets created in the the courses_students table.
Related
I've been trying to find a way to achieve this but I cannot find any attempts even so I am thinking that maybe my approach is completely wrong. That said, what should I do in my migration if I want a combination of two fields to be unique? Please note that I do not want them to be indexes, just database fields.
For example, for the migration below, I can separately add unique: true to the fields, but the combo?
class CreateSomething < ActiveRecord::Migration
def change
create_table :something do |t|
t.date :datestamp, :null => false
t.integer :some_number, :null => false
t.timestamps
end
end
end
I'm not sure what you mean by
Please note that I do not want them to be indexes, just database fields.
Indexes are extra pieces on information that the database stores about the columns.
More importantly an index is exactly what you need!
class CreateSomething < ActiveRecord::Migration
def change
create_table :something do |t|
t.date :datestamp, :null => false
t.integer :some_number, :null => false
t.timestamps
end
add_index :something, [:datestamp, :some_number], unique: true
end
end
I wanna rename the column id, how do I do?
I want to set number to primary key and auto increment, and id to just string of user id.
How do I do?
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :user
t.timestamps
end
rename_column :users, :id, :number
end
end
I did like above, but it didn't work.
Even if I wouldn't recommend it, here is how I guess you can do it:
in your migration:
def up
create_table :users, id: false do |t|
t.string :user
t.integer :number, null: false, index: true, unique: true
t.timestamps
end
execute %Q{ ALTER TABLE "users" ADD PRIMARY KEY ("number"); }
end
def down
drop_table :users
end
in your model:
self.primay_key = 'number'
I use postgresql 9.3, Ruby 2.0, Rails 4.0.0.
After reading numerous questions on SO regarding setting the Primary key on a table, I generated and added the following migration:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, { id: false, primary_key: :uid } do |t|
t.integer :uid, limit: 8
t.string :name
t.integer :shares
t.timestamps
end
end
end
I also added self.primary_key = "uid" to my model.
The migration runs successfully, but when I connect to the DB using pgAdmin III I see that the uid column is not set as primary key. What am I missing?
Take a look at this answer. Try to execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);" without specifying primary_key parameter in create_table block.
I suggest to write your migration like this (so you could rollback normally):
class CreateShareholders < ActiveRecord::Migration
def up
create_table :shareholders, id: false do |t|
t.integer :uid, limit: 8
t.string :name
t.integer :shares
t.timestamps
end
execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);"
end
def down
drop_table :shareholders
end
end
UPD: There is natural way (found here), but only with int4 type:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, id: false do |t|
t.primary_key :uid
t.string :name
t.integer :shares
t.timestamps
end
end
end
In my environment(activerecord 3.2.19 and postgres 9.3.1),
:id => true, :primary_key => "columname"
creates a primary key successfully but instead of specifying ":limit => 8" the column' type is int4!
create_table :m_check_pattern, :primary_key => "checkpatternid" do |t|
t.integer :checkpatternid, :limit => 8, :null => false
end
Sorry for the incomplete info.
I have created migrations like this:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, id: false do |t|
t.integer :uid, primary_key: true
t.string :name
t.integer :shares
t.timestamps
end
end
end
Is it necessary to add_index on HABTM join table? I use t.belongs_to (aka t.references). Here is code
class CreateCohortsUsersTable < ActiveRecord::Migration
def change
create_table :cohorts_users, :id => false do |t|
t.belongs_to :cohort
t.belongs_to :user
end
add_index :cohorts_users, :cohort_id # Do I need this?
add_index :cohorts_users, :user_id # Do I need this?
end
end
It's usually a good idea to add a unique index on both columns:
add_index :cohorts_users, [:cohort_id, :user_id], unique: true
I'm trying to use a :has_many :through type association, but I'm getting the following error:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: work_units.developer_id:
Many other posts about this sort of thing have just had spelling mistakes, but I've checked mine.
class Developer < ActiveRecord::Base
attr_accessible :skype_name, :language_ids, :user_attributes
has_many :work_units
has_many :projects, :through => :work_units
...
end
class Project < ActiveRecord::Base
attr_accessible :complete, :description, :finalised, :price
has_many :work_units
has_many :developers, :through => :work_units
...
end
class WorkUnit < ActiveRecord::Base
attr_accessible :hours_worked
belongs_to :project
belongs_to :developer
end
I've run db:migrate and it didn't complain. I did make a mistake and had to rollback the db then re-migrate, but I think I did it right. I use the annotate gem and it doesn't show any of the relationship ids I'd expect. So, do I need to create a WorkUnits table or am I missing something? The rails guide didn't mention manually making tables.
Edit
Here's the migration I used to create the WorkUnit model and stuff:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.timestamps
end
end
end
Edit 2
Snippets from my schema.rb:
create_table "work_units", :force => true do |t|
t.integer "hours_worked", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "projects", :force => true do |t|
t.string "description"
t.decimal "price", :precision => 8, :scale => 2
t.boolean "complete", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
Similarly for :developers. So, why doesn't my migration add the association information for me?
Your WorkUnit migration should look like this:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.references :developer
t.references :project
t.timestamps
end
add_index :work_units, :developer_id
add_index :work_units, :project_id
end
end
You need to add the foreign keys to your work_units table.
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.integer :project_id, null: false
t.integer :developer_id, null: false
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
Another way:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.belongs_to :project
t.belongs_to :developer
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
You can also define these fields when generating your model, then they'll be added to the migration automatically as show in the second snippet.
$ rails g model WorkUnit hours_worked:integer project:belongs_to developer:belongs_to
Hope that helps.
A table for WorkUnit needs to exist, whether that means it migration was automatically generated via scaffolding or if the migration was manually written by you.
If you don't have a migration yet that creates that table, you'll need to create that migration because the table does need to exist.
You do need a work_units table with a project_id and developer_id column.
Have a look at http://xyzpub.com/en/ruby-on-rails/3.2/activerecord_datenbank_anlegen.html if you don't know how to create a table.