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.
Related
I have two models: Account and Profile. In Account I have role column. I need to add role column to profiles table.
I include in Profile has_one :account association and belongs_to :profile in Account model. I think the solution is near that.
profile.rb
class Profile < ApplicationRecord
has_one :account
end
acount.rb
class Account < ApplicationRecord
devise :registerable, :database_authenticatable, :rememberable,
:trackable, :confirmable, :lockable, :recoverable, :validatable
belongs_to :profile, foreign_key: 'profile_id'
enum role: %i[user admin]
end
schema.rb
create_table "accounts", 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.string "remember_token"
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.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.integer "failed_attempts", default: 0, null: false
t.string "unlock_token"
t.datetime "locked_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "profile_id", null: false
t.integer "role", default: 0
t.index ["profile_id"], name: "index_accounts_on_profile_id"
end
create_table "profiles", force: :cascade do |t|
t.string "last_name", null: false
t.string "first_name", null: false
t.string "middle_name"
t.string "email", null: false
t.text "about"
t.date "hire_date", null: false
end
I want to which is in profiles table to be added in column Account.role.
how about just using a function which access the role data from accounts
class Profile < ApplicationRecord
def role
return account.role unless account.nil?
end
end
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
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 strive to bind cart object with Devise current_user in my carts_controller.rb:
class CartsController < ApplicationController
def show
#cart = Cart.find_or_create_by(user_id: current_user.id)
#products = #cart.products
end
end
It causes such error:
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column carts.user_id does not exist
LINE 1: SELECT "carts".* FROM "carts" WHERE "carts"."user_id" = $1 ...
^
: SELECT "carts".* FROM "carts" WHERE "carts"."user_id" = $1 LIMIT $2):
It`s predictable result, because my cart model:
class Cart < ApplicationRecord
belongs_to(:account, optional: true)
has_and_belongs_to_many(:products)
end
has association with user through one account:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one(:cart, through: :account)
has_one(:account)
end
That is my schema.rb:
ActiveRecord::Schema.define(version: 20161201120324) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "accounts", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.float "balance"
t.index ["user_id"], name: "index_accounts_on_user_id", using: :btree
end
create_table "carts", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "account_id"
t.index ["account_id"], name: "index_carts_on_account_id", using: :btree
end
create_table "users", force: :cascade do |t|
t.string "name"
t.integer "age"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email"
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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "accounts", "users"
add_foreign_key "carts", "accounts"
end
Could I refer to current_user just by adding referenced user_id field into my carts table or it neccessarily does via corresponding account?
You need to add user_id to carts and association in Cart:
belongs_to :user
and then the thing you are trying to do in controller should work.