Im having an issue with MySql.Created a boolean column(Via a Database Migration) in MySql Database,toggled the value to "true".I Have a method in my rails App that checks if the value in that column is true,but it always returns false(even when called from a ruby console). Tried using the Same Migration on a SQLite Database and the same code returns true on the same Column. Observed MySQL uses tinyint for boolean values(1 == true) .
Please how can i correct this?
My Migration:
def self.up
create_table :users do |t|
t.string :name
t.string :email
t.boolean :admin , default => false
...
t.timestamps
end
end
...
Then i used the Faker Gem to Populate my Database, toggling one user in it setting it's value to true
Sample Data Via Faker Gem
admin = User.create!(:name => "sample",
:email => "sample#sample.com",
:password => "sample",
:password_confirmation => "sample")
admin.toggle!(:admin) #toggling value of admin to true just for this user
Related
I am very new to Ruby and trying to complete a tutorial that I can't get to work properly. I am attempting to run rake db:migrate on my root folder and is giving me 3 separate error messages:
>rake db:migrate
rake aborted!
SyntaxError:
C:/Users/Bill/Sites/simple_cms/db/migrate/20170922050429_create_use
rs.rb:4: syntax error, unexpected keyword_do_block
create_table :users, do |t|
^
C:/Users/Bill/Sites/simple_cms/db/migrate/20170922050429_create_users.rb:5:
syntax error, unexpected tSTRING_BEG, expecting keyword_end
t.column "first_name", :string, :limit => 25
^
C:/Users/Bill/Sites/simple_cms/db/migrate/20170922050429_create_users.rb:5:
syntax error, unexpected ',', expecting keyword_end
t.column "first_name", :string, :limit => 25
^
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
The Ruby code from my create_users.rb file is:
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users, do |t|
t.column "first_name", :string, :limit => 25
t.string "last_name", :limit => 50
t.string "email", :default => "", :null => false
t.string "password", :limit => 40
t.timestamps
end
end
I am not sure what I am doing wrong here. Any insight would be appreciated!
in addition to first answer. Why don't you use rails generators?
Write migrations can be usefull when you have to modify something. Faster and cleaner way is using rails generators:
Example:
rails g model User first_name:string last_name:string
If attributes are string you can just
rails g model User first_name last_name
It will generate class User in /app/models/user.rb and migration for database.
Also you have Scaffold, and others generators.
More info: Command Line Rails
Tip: Check for Devise Gem, it will generate entire structure for User Model.
Link: Devise Gem
In your code:
def change
create_table :users, do |t|
t.column "first_name", :string, :limit => 25
t.string "last_name", :limit => 50
t.string "email", :default => "", :null => false
t.string "password", :limit => 40
t.timestamps
end
end
You have:
create_table :users, do |t|
which should be:
create_table :users do |t|
There should not be any comma after that unless you have more than one arguments there.
Update:
And also you class has no end which will not close the class definition and throw exception.
On a side note:
You have this line:
t.column "first_name", :string, :limit => 25
which can be written as:
t.string "first_name", :limit => 25
Hope this helps.
I am trying to make it so certain columns cannot be null. I use change_column no problem but some of these columns have an index attached to them signifying that it is unique.
However when I run this migration:
change_column :users, :username, :string, null: false
change_column :users, :email, :string, null: false
change_column :users, :password, :string, null: false
change_column :users, :terms_agreed, :boolean, null: false
It removes the add_index in the schema
schema.rb
- add_index "users", ["username"], :name => "index_users_on_username_code", :unique => true
- add_index "users", ["email"], :name => "index_users_on_email_code", :unique => true
add_index "users", ["confirmation_code"], :name => "index_users_on_confirmation_code", :unique => true
How do I do this without removing the indexes?
P.S. its not actually removing the indexes in the database. Just in the schema.rb file.
The behaviour of how migrations are treated depends on you database implementation. More info here, but in your migration you should explicitly request an index in your change.
class DoSomethingToTable < ActiveRecord::Migration
def change
change_column :users, :username, :string, null: false, index: true
end
end
See the docs for more information.
So still unclear as to what happened, but turns out that the indexes got deleted from the database during some database manipulation.
I just put the schema back the way I needed it to be and ran rake db:setup then my migration again and everything worked fine. Very confusing and a lot of unnecessary time spent trying to figure it out.
I'm just following this RoR tut, I'm doing it the same way but I'm stuck creating a table:
$ rails generate model User
invoke active_record
create db/migrate/20140718180319_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
This is my xxxxx_create_users.rb
class CreateUsers < ActiveRecord::Migration
def Up
create_table :users do |t|
t.column "first_name", :string, :limit => 25
t.string "last_name", :limit => 50
t.string "email", :default => "", :null => false
t.string "password", :limit => 40
t.timestamps
end
end
def down
drop_table :users
end
end
When I run db:migrate the table is not being created:
$ rake db:migrate
== 20140718182504 CreateUsers: migrating ======================================
== 20140718182504 CreateUsers: migrated (0.0000s) =============================
Is missing
create_table(:users)
-> x.xxxxxs
What am I doing wrong? Thanks.
Isn't it a typo with your "Up" migration method? Try with:
def up
instead of:
def Up
I have previously created localhost-only RoR applications where models were created manually with scaffolds generated for them, creating a nice, quick, easy to use CRUD interface for the data. I did this in Netbeans using SQLite.
Now I have a server with a MySQL database and wish to create a quick CRUD application which provides a quick and easy way to view data in the database and give a few options like edit/delete. As my database is already specified by MySQL this seems to open up a massive can of worms, making this a lot less straight forward in comparison to my Netbeans venture into scaffold-generated crud web apps in RoR.
I have looked into dumping the schema of my current database, db:raking it, then generating the scaffolds. Is this the correct approach? I have also read about Magic Model Generator. Is this the best way to go about getting the MySQL database to a RoR model format? http://magicmodels.rubyforge.org/magic_model_generator/
I guess what I'm asking is, for my database structure, is RoR appropriate to mock-up a quick CRUD web app so that the data can have basic manipulation performed on it?
Below is the schema.rb for my MySQL database. There is a FK relationship on userId and attachmentId.
ActiveRecord::Schema.define(:version => 0) do
create_table "attachments", :primary_key => "attachmentId", :force => true do |t|
t.string "attachmentName", :null => false
t.string "fileType", :limit => 30, :null => false
t.binary "content", :null => false
t.string "printCode"
end
create_table "emails", :primary_key => "emailId", :force => true do |t|
t.integer "userId", :limit => 11, :null => false
t.integer "attachmentId", :limit => 11, :null => false
t.string "body", :limit => 1000
t.string "subject"
end
add_index "emails", ["attachmentId"], :name => "attachmentId", :unique => true
add_index "emails", ["userId"], :name => "userId"
create_table "printUsers", :primary_key => "userId", :force => true do |t|
t.string "email", :null => false
end
add_index "printUsers", ["email"], :name => "email", :unique => true
end
There seem to be several approaches to using rails with an existing database. See Connect rails to existing postgres DB - models not seen by console and controllers, and especially the links from it: http://magicmodels.rubyforge.org/magic_model_generator/ and http://blog.aizatto.com/2007/05/21/activerecord-without-rails/
It's good to point out that you don't need to use ActiveRecord with rails. Your model can be any Object, so it might be easier to use something like sequel or arel to access the data.
Another approach would be to migrate the data out of your existing database and into a new one that you generate by scaffolding your models.
I have a ruby script that is using ActiveRecord (2.3.12) to access a MySQL database. The flow goes something like, "read database values from a config file", "connect to database", "Create table A if it doesn't exist", "download and parse a file", "save parsed records to A".
The code looks like the following:
ActiveRecord::Base.establish_connection(
:adapter => 'mysql',
:database => database_name,
:username => username,
:password => password,
:host => "localhost",
:port => 3306
)
...
ActiveRecord::Schema.define do
create_table a, :force => true do |t|
t.string :last_name, :limit => 60, :default => "", :null => false
t.string :first_name, :limit => 30, :default => "", :null => false
t.string :middle_initial, :limit => 2, :default => ""
t.string :dob, :limit => 12, :default => "", :null => false
end
end unless A.table_exists?
However, if I put incorrect DB credentials, or a non-existent database name into the establish_connection method, the script doesn't seem to give any errors or throw any exceptions until I actually try to perform some operation on the database (i.e., create table A). I tried a begin-rescue-end around establish_connection, but it never went into the rescue block.
Why does establish_connection seem to not really...well...establish the connection? And for the life of me, I can't figure out what it is even supposed to return. The docs HERE sure don't seem to be any help.
Or am I doing something wrong? Please help!
I usually use ActiveRecord::Base.connection.active? statement to check the whether the ActiveRecord is really connected to database.
def establish_database_connection
begin
ActiveRecord::Base.establish_connection config["database"]
ActiveRecord::Base.connection.active?
logger.info "Connected to Database"
rescue Exception => e
logger.error "Exception db connection : #{e.message} "
raise "Database connection failed"
end
end
Without ActiveRecord::Base.connection.active? statement the above code won't raise any error on invalid credentials.
RSK's solution will leave a connection checked out for the current thread. If you don't want that, try this (adapted from https://gist.github.com/limhoff-r7/71ee6b1568b604e131a8, which is for Postgres only):
ActiveRecord::Base.establish_connection
# Check if the spec passed to `ActiveRecord::Base.establish_connection` can connect to the database.
#
# #return [true] if an active connection can be made to the database using the current config.
# #return [false] if an active connection cannot be made to the database.
def connection_established?
begin
# use with_connection so the connection doesn't stay pinned to the thread.
ActiveRecord::Base.connection_pool.with_connection {
ActiveRecord::Base.connection.active?
}
rescue Exception
false
end
end
I agree with #Luke Imhoff: Connections that are manually checked out from ActiveRecord's connection-pool, have to manually be returned to the pool.
As a note, however, I suggest to use the connection that ActiveRecord yields to the block
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? }
Referring to the documentation of :with_connection:
I'm not an expert, but I always assumed that establish_connection was more of a connection definition, whereas the actual connection is made when it is used, in this case, when the table_exists? runs