When I run rake db:seed in my Rails 3 application I get the error:
rake aborted!
undefined method 'find_or_create_by_first_name_and_last_name_and_role_and_email_and_password_and_password_confirmation'
Below are my create_users.rb and seeds.rb files respectively. Why isn't the find_or_create_by_* method being dynamically created?
def self.up
create_table :users do |t|
t.string :first_name, :null => false
t.string :last_name, :null => false
t.string :role, :null => false
t.string :email, :null => false
t.string :crypted_password, :null => false
t.string :password_salt, :null => false
t.string :persistence_token, :null => false
t.string :current_login_ip
t.string :last_login_ip
t.datetime :current_login_at
t.datetime :last_login_at
t.timestamps
end
end
User.find_or_create_by_first_name_and_last_name_and_role_and_email_and_password_and_password_confirmation(...)
According to the docs:
This dynamic finder is called with find_or_create_by_ and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won’t be set unless they are given in a block. (emphasis mine)
I'm guessing password and password_confirmation are protected attributes.
You are missing "and" between role and email
User.find_or_create_by_first_name_and_last_name_and_role_and_email_and_password_and_password_confirmation(...)
Related
This question already has answers here:
A migration to add unique constraint to a combination of columns
(6 answers)
Closed 7 years ago.
Based off http://guides.rubyonrails.org/v3.2.21/migrations.html and
given the following migration:
class CreateVacations < ActiveRecord::Migration
def change
create_table :vacations do |t|
t.string :name
t.string :slug, :uniqueness => true
t.datetime :starts_at
t.datetime :ends_at
t.timestamps
end
end
end
I ran rake db:migrate and see this schema:
ActiveRecord::Schema.define(:version => 20150825170615) do
create_table "vacations", :force => true do |t|
t.string "name"
t.string "slug"
t.datetime "starts_at"
t.datetime "ends_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
I do not ssee any uniqueness requirement for 'slug'. If I did it wrong, how can I fix it at this point?
If it was right, why doesn't the schema say it's unique? Thank you
You need to create an index in order to enforce uniqueness at the database level:
add_index :vacations, :slug, unique: true
rails not null / unique in migrations doesn't trigger error :S
class CreateDeditProjects < ActiveRecord::Migration
def change
create_table :dedit_projects do |t|
t.string :name, :null => false
t.string :uid, :unique => true
t.boolean :status
t.timestamps null: false
end
end
end
empty name doesn't trigger error. Neither does duplication of uid.
This is what I see in schema.db
ActiveRecord::Schema.define(version: 20150410105216) do
create_table "dedit_projects", force: :cascade do |t|
t.string "name", null: false
t.string "uid"
t.boolean "status"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
hm, I need to add indexes somewhere I guess? Shouldn't that be automatic?
Not null problem is bogus though.
Rails automatically adds index on id and references and maybe on some other types. If You want to add new index, You can create a migration:
def change
add_index :dedit_projects, :uid, unique: true
end
You can also use validations validates_uniqueness_of and validates_presence_of in models. Although I don't understand why doesn't it work as it is :)
Uniqueness is a property of the index so you need either a separate call to add_index or write it like so
create_table :dedit_projects do |t|
t.string :uid, index: {unique: true}
...
end
I have two models...
create_table "registrations", :force => true do |t|
t.integer "orientation_id"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "student_id"
...
end
create_table "orientations", :force => true do |t|
t.date "class_date"
t.text "class_time"
t.integer "seats"
t.boolean "active", :default => true
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I want to create a validation in my registration model that says the student_id must be unique in each Orientation.
If i understood your question correctly,you want the scope option of the validates_uniqueness_of.If so,this should work
In your Registration model,
Class Registration < ActiveRecord::Base
......
validates_uniqueness_of :student_id, scope: :orientation_id
end
And also,you should be generating a migration to add this
add_index :registration, [ :student_id, :orientation_id ], :unique => true
More Info here
I am a newbie in rails; my problem is:
I have a table for users, and I need to add more fields...
Where do I put that?
I tried to put it in the migration file, but the schema doesn't change when I run rake db:migrate.
This is in my migration file:
def self.up
create_table :users do |t|
t.string :username, :null => false # if you use another field as a username, for example email, you can safely remove this field.
t.string :email, :default => nil # if you use this field as a username, you might want to make it :null => false.
t.string :crypted_password, :default => nil
t.string :salt, :default => nil
t.string :nombres, :default => nil
t.string :apellidos, :default => nil
t.string :codigo, :default => nil
t.string :fecha, :default => nil
t.string :zona, :default => nil
t.string :institucion, :default => nil
t.string :frecuencia, :default => nil
t.string :pregunta, :default => nil
t.string :respuesta, :default => nil
t.timestamps
end
And the schema is still without new fields
create_table "users", :force => true do |t|
t.string "username", :null => false
t.string "email"
t.string "crypted_password"
t.string "salt"
t.string "nombres"
t.string "apellidos"
t.string "codigo"
t.string "fecha"
t.string "zona"
t.string "institucion"
t.string "frecuencia"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "remember_me_token"
t.datetime "remember_me_token_expires_at"
end
What should I do?
Simple migration
You can use a migration generator:
$> rails g migration add_position_to_users position:integer
then run
$> rake db:migrate
More complex migration
or more complex migration which rails also provide:
$> rails g migration add_body_and_pid_to_users body:string:index pid:integer:uniq:index
$> rake db:migrate
More information about migrations can be found at railsguides
http://guides.rubyonrails.org/migrations.html
I think something we're not mentioning here is adding the code into the migration file.
My steps to add a column go something like this:
# rails generate migration AddFieldName blah:string
Inside the migration file generated:
(btw, this typically looks like: db/migrations/20130330115915_add_field_name.rb)
class AddFieldName < ActiveRecord::Migration
def change
add_column :table_name, :blah, :string
end
end
After making this change, I then run db:migrate. Then, the column is added to the database.
I am creating a forum software. I want admins and mods to be able to close certain topics.
Codes are sanitized to show only relevant info.
Models
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation, :bio
has_many :topics, dependent: :destroy
end
class Topic < ActiveRecord::Base
belongs_to :user
attr_accessible :name, :last_post_id, :content
end
Schema for user: admin and mod columns determine admins and mods.
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "password_digest"
t.string "remember_token"
t.boolean "admin", :default => false
t.text "bio"
t.boolean "mod", :default => false
end
Schema for topic: closed column determines topic's closed status.
create_table "topics", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "forum_id"
t.string "name"
t.integer "last_post_id"
t.integer "views"
t.integer "user_id"
t.boolean "closed", :default => false
t.text "content"
end
I am reluctant to user attr_accessible :closed for TOPIC model because it will be vulnerable to malicious PUT request (correct me if I am wrong).
Is there some way for Rails app to be able to access and modify value of closed column of TOPIC without using attr_accessible, so that only mods and admins can edit them?
I searched on google and found this ascii cast.
Basically, you are looking for dynamic attr_accessible.
If you currently have
class Article < ActiveRecord::Base
attr_accessible :name, :content, :closed
end
You ca use dynamic attr_accessible like this :
class Article < ActiveRecord::Base
attr_accessible :name, :content
private
def mass_assignment_authorizer
super + [:closed]
end
end
I hope I is what you are looking for.
Be sure to check the link I gave you for complete reference.