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

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

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

Sequel : DRY between schema migration and model validate method

I'm wondering if I miss a way to avoid repeat validation code in my Sequel::Model#validate subclass method since I've already put all constraints into my migration file.
Here's a simple example of what I'm talking about :
Sequel.migration do
change do
create_table :users do
primary_key :id
String :name, :null => false, :unique => true
end
end
end
class User < Sequel::Model
def validate
super
validates_presence :name
validates_unique :name
validates_type String :name
end
end
It seems very painful and errors prone to have to repeat all the constraints in the validate method. Did I miss something or there's no other way to do that ?
Any advice will be appreciated, thanks
Sequel has some nice plugins and extensions.
Sequel::Model.plugin(:auto_validations)
Sequel::Model.plugin(:constraint_validations)
and
DB.extension(:constraint_validations)
auto_validations
The auto_validations plugin automatically sets up three types of
validations for your model columns:
type validations for all columns
not_null validations on NOT NULL columns (optionally, presence
validations)
unique validations on columns or sets of columns with unique indexes
See http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/AutoValidations.html
constraint_validations
The constraint_validations extension is designed to easily create
database constraints inside create_table and alter_table blocks. It
also adds relevant metadata about the constraints to a separate table,
which the constraint_validations model plugin uses to setup automatic
validations.
See http://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/constraint_validations_rb.html
and
http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/ConstraintValidations.html
Your example would look like this
Sequel::Model.plugin(:auto_validations)
Sequel::Model.plugin(:constraint_validations)
Sequel.migration do
up do
extension(:constraint_validations)
create_table :users do
primary_key :id
String :name, :null => false, :unique => true
validate do
presence :name,
name: :presence_name
end
end
end
down do
extension(:constraint_validations)
drop_table(:users)
end
end
class User < Sequel::Model
end
I think, it's normal. Don't worry.

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

(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