This is my first publication in stack overflow, I hope you can help me.
I'm working with RoR and PostgreSQL, gem 'devise'.
In rails console I am trying to delete data from the "Competitor" table, but I have the following error and I have not been able to solve it.
2.4.1 :006 > c.destroy(c)
ActiveRecord::UnknownPrimaryKey: Unknown primary key for table competitors in model Competitor.
This is my competitors table, which it's was generate with model of gem devise
create_table "competitors", id: false, force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.bigint "rut"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "lastname"
t.integer "phone"
t.date "dateOfBirth"
t.boolean "gender"
t.string "numberSerie"
t.string "otp_secret_key"
t.integer "otp_module", default: 0
t.index ["email"], name: "index_competitors_on_email", unique: true
t.index ["reset_password_token"], name: "index_competitors_on_reset_password_token", unique: true
t.index ["rut"], name: "index_competitors_on_rut", unique: true
endere
and this is the model
class Competitor < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :raffle_registers, primary_key: 'rut', foreign_key: 'rutCompetitors'
has_many :accountpays
has_one :found
#otp model to make it use TFA
has_one_time_password
enum otp_module: { disabled: 0, enabled: 1 }, _prefix: true
attr_accessor :otp_code_token
end
You generated the competitors table without primary key. Checkout this line:
create_table "competitors", id: false, force: :cascade do |t|
The id: false is your issue. Check the migration to create the competitors table and set a primary key (or create a new migration adding a primary key to it).
Useful resource: https://stackoverflow.com/a/10079409/740394
Related
Hello i have an issue with my app Rails when i try to create an "Enfant" who belongs to an user and a Nounou but my problem is when i create an "enfant" i'm a user with an ID but, I haven't chosen yet a nounou so i haven't got a nounou_id this is my differents code(i try to put optional: true but it doesn't work :
Models and Schema
class Enfant < ApplicationRecord
belongs_to :user
belongs_to :nounou, optional: true
end
class Nounou < ApplicationRecord
has_many :enfants
end
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :enfants
end
create_table "enfants", force: :cascade do |t|
t.string "last_name"
t.string "first_name"
t.bigint "nounou_id", null: false
t.bigint "user_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["nounou_id"], name: "index_enfants_on_nounou_id"
t.index ["user_id"], name: "index_enfants_on_user_id"
end
create_table "nounous", force: :cascade do |t|
t.string "name"
t.integer "price"
t.string "localisation"
t.integer "evaluation"
t.integer "places"
t.string "first_name"
t.string "last_name"
t.string "photo"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "username"
t.string "photo"
t.string "first_name"
t.string "last_name"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
Thanks a lot it was in my migration file : t.bigint "nounou_id"
t.bigint "user_id", null: false I delete null:false for nounou_id and it works ;)
I ran into a similar problem when attempting to add a user_id column to a cats table. It kept returning the same NotNullViolation Error. This worked for me, to clear the error so that I was able to keep the "null: false" constraint on the column added to the table. Most likely I am running into the error because there are already cats without users. Run the below commands and it should fix the error for you as well. I learned about this trick from this other question.
rails db:drop
rails db:create
rails db:migrate --trace
There are two problems with the null: false option:
It doesn't consider that the belongs_to association could be optional.
If there are already records in the database, running the migration will generate an Exception, as there is not a default value (in PostgreSQL, PG::NotNullViolation: ERROR: column "user_id" contains null values).
Here's the reference.
Solution:
Your form probably is sending nounou_id as nil or something. You need to verify that by inspecting your params reaching your create method.
You have made nounou_id optional in model only but you need to run a migration to make it optional in db too where it clearly says it can't be false (null: false).
You can take help for that migration from here.
You should modify your enfant_params method in rails:
def enfant_params
params.require(:enfant).permit(:last_name, :first_name, :user_id, :nounou_id)
end
I am confident that this will solve your issue but if you still need help, update your question with your form code, create action and enfant_params and updated schema.
Good Luck.
I just added rolify to my Rails 6 app, which is using UUID for all tables.
After the initial errors I found that I need to change my migrations slightly to deal with the UUID. I am also using a model named 'Person' instead of the default 'User'.
I have tried restarting my server (several times) but I still get the following:
2.6.2 :002 > p.add_role :admin
Traceback (most recent call last):
1: from (irb):2
NoMethodError (undefined method `add_role' for #Person::ActiveRecord_Relation:0x00007fe37ec29408>)
2.6.2 :003 >
Here are the applicable models:
role.rb
class Role < ApplicationRecord
has_and_belongs_to_many :people, :join_table => :people_roles
belongs_to :resource,
:polymorphic => true,
:optional => true
validates :resource_type,
:inclusion => { :in => Rolify.resource_types },
:allow_nil => true
scopify
end
person.rb
class Person < ApplicationRecord
rolify
def full_name
"#{self.last_name}, #{self.first_name}"
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable
end
applicable schema:
create_table "people", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "last_name"
t.string "first_name"
t.string "gender"
t.uuid "personable_id"
t.string "personable_type"
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.integer "failed_attempts", default: 10, null: false
t.string "unlock_token"
t.datetime "locked_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "type"
t.index ["email"], name: "index_people_on_email", unique: true
t.index ["reset_password_token"], name: "index_people_on_reset_password_token", unique: true
t.index ["unlock_token"], name: "index_people_on_unlock_token", unique: true
end
create_table "people_roles", id: false, force: :cascade do |t|
t.uuid "person_id"
t.uuid "role_id"
t.index ["person_id", "role_id"], name: "index_people_roles_on_person_id_and_role_id"
end
create_table "roles", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "resource_id"
t.string "resource_type"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
t.index ["name"], name: "index_roles_on_name"
end
Any help on this would be much appreciated!
Your problem is that p is not a Person but a collection of Person objects as indicated by ActiveRecord_Relation.
If you would like all of those people to have the admin role then it would be
p.each {|person| person.add_role :admin }
Otherwise you will need to change the code that populates p to return a single Person object. For instance if you are populating p as
p = Person.where(uuid: some_uuid)
Then change this to
p = Person.find_by(uuid: some_uuid) # or Person.find_by_uuid(some_uuid)
find_by will return an instance of the class (or nil none are found) by selecting the first record where the condition is true. Since uuid by virtue is unique this should not be an issue.
I'm working on a issue with Single Table Inheritance. I have two different types of Users. User model and Trainer model, Trainer user should inherit attributes from the User model. I created a User in the rails console and everything worked. As soon as I attempted to create a Trainer I get the following error.
Rails 5.0.4
ActiveRecord::RecordInvalid: Validation failed: User must exist
Am I setting up my model associations incorrectly?
Here is my User Model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
My Trainer Model
class Trainer < User
has_many :appointments
has_many :clients, through: :appointments
end
Schema for models
create_table "trainers", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "type"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
As you can see from my User model, I added the required :type column
Here is the schema for my client and appointment
create_table "appointments", force: :cascade do |t|
t.integer "client_id"
t.integer "trainer_id"
t.datetime "appointment_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "start_time"
t.datetime "end_time"
t.integer "status", default: 0
end
create_table "clients", force: :cascade do |t|
t.string "name"
t.string "phone_number"
t.integer "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
First I created a user in the console
User.create!(email:'ryan#test.com', password:'asdfasdf', password_confirmation:'asdfasdf')
Then I when on to create a Trainer
Trainer.create!(first_name:'Ryan', last_name:'Bent')
Trainers and Users should be associated. But I didn't think I needed add associations using Single Table Inheritance.
With Single Table Inheritance, one table must have all the attributes that any of the subclasses need (more information). So for your situation, you'd need to add the Trainer columns (first_name, last_name) to the users table as well, and then Users would leave that empty on the table and Trainers would fill them in.
If you want to keep the separate tables, what you are doing is no longer single table and would require some sort of joining between the 2.
I’m new to unit test and Rails in general. I have a simple Rails application and trying unit test it with the default Minitest and Capybara. Unfortunately, its giving me this error regardless of what's I’m tiring to test
E
Error:
StocksControllerTest#test_the_truth:
ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: UNIQUE constraint failed: admins.email: INSERT INTO "admins" ("created_at", "updated_at", "id") VALUES ('2017-06-28 08:49:33.148641', '2017-06-28 08:49:33.148641', 298486374)
bin/rails test test/controllers/stocks_controller_test.rb:10
test/controllers/stocks_controller.rb
require 'test_helper'
class StocksControllerTest < ActionDispatch::IntegrationTest
def setup
#base_title = "Stationery Management System"
end
test "the truth" do
assert true
end
end
Schema.rb
ActiveRecord::Schema.define(version: 20170627120530) do
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_admins_on_email", unique: true
t.index ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
end
create_table "stocks", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "admin_id"
t.index ["admin_id"], name: "index_stocks_on_admin_id"
end
end
models/stock.rb
class Stock < ApplicationRecord
belongs_to :admin
end
models/admin.rb
class Admin < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :stocks, dependent: :destroy
end
Keep in mind that the application seem to function pretty well. I did try to drop reset my test DB but it didn’t help. Would be graceful for any help.
I'm following a guide on Devise and I am currently stuck with this:
`NoMethodError in TasksController#new undefined method `tasks' for nil:NilClass
Task.rb
class Task < ActiveRecord::Base
belongs_to :user
end
User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :tasks
end
TaskController.rb
def new
#task = current_user.tasks.build
end
def create
#task = current_user.tasks.build(task_params)
end
DB - Schema.rb
create_table "tasks", force: :cascade do |t|
t.string "name"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Help is much appreciated!
Error message says: nil.tasks
It means the User class object is not created.
Try to login. Once you are logged in, the error will be resolved.