I'm trying to add some seed data to my database, but ActiveRecord won't let me create a category without an associated user.
ActiveRecord::Schema.define(version: 2020_07_18_233635) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "categories", force: :cascade do |t|
t.string "name"
t.bigint "user_id"
t.string "image_url"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["user_id"], name: "index_categories_on_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.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
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
add_foreign_key "categories", "users"
add_foreign_key "goals", "categories"
end
When I try to create a category:
category = Category.create!({name: 'Fitness', image_url: 'some_url'})
I get this error:
ActiveRecord::RecordInvalid (Validation failed: User must exist)
EDIT:
Here's my Category class:
class Category < ApplicationRecord
belongs_to :user
has_many :goals
end
Prior to Rails 5, the default for a belongs_to association was that it was optional. However, for Rails >= 5, the reverse is true; the presence of an associated object is checked by default. Specify :optional on the association to opt out of that:
class Category < ApplicationRecord
belongs_to :user, optional: true
has_many :goals
end
Related
As of right now i have the user model from the Devise gem, and i have also created a Player model to store information that i need for my app. All I'm trying to do is make a new Player whenever a User creates an account. The Player model has 3 columns - one for the user_id, one for the game_id and one for the deck_id.
#schema.rb
create_table "games", force: :cascade do |t|
t.text "players"
t.integer "player_count"
t.boolean "rogue", default: true
t.boolean "wizard", default: true
t.boolean "paladin", default: true
t.boolean "barbarian", default: true
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "last_selected_deck"
end
create_table "players", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "game_id"
t.integer "company_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["company_id"], name: "index_players_on_company_id"
t.index ["game_id"], name: "index_players_on_game_id"
t.index ["user_id", "game_id"], name: "index_players_on_user_id_and_game_id", unique: true
t.index ["user_id"], name: "index_players_on_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.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "company_id", null: false
t.string "username"
t.integer "game_id"
t.index ["company_id"], name: "index_users_on_company_id"
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
#user.rb
class User < ApplicationRecord
after_create :create_player
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
belongs_to :company
has_one :player, dependent: :destroy
has_one :game, through: :player
def create_player
#code
end
end
i thought i could create a method inside the user.rb model that should be executed after creation, but it doesn't seem to work
You have declared the user-player association, so you can do something like this:
def create_player
self.player.create!
# Player.create!(user_id: self.id) # without taking account assiciation
end
Hope it helps!
I am making a notes app using Active Admin for the first time and I am running into an error that confuses me because the relationship exists my migrations are present as far as I can see in the schema. I have 2 models currently Note that belongs_to Content and Content has_many :notes . I am trying to customize my show for Contents so it will display differently as seen below but I keep getting a no method error for notes this relationship is present and should work as it is a foreign key between both tables?
class Note < ApplicationRecord
belongs_to :content
end
class Content < ApplicationRecord
has_many :notes
end
ActiveAdmin.register Content do
permit_params :name, note_ids: []
show title: 'Test' do
h3 'You have ' + pluralize(content.notes.count, 'note') + ' referencing ' + `#{content.name}`
end
ActiveRecord::Schema.define(version: 2021_05_06_140826) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_type"
t.bigint "resource_id"
t.string "author_type"
t.bigint "author_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id"
end
create_table "admin_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.index ["email"], name: "index_admin_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
end
create_table "contents", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "notes", force: :cascade do |t|
t.string "title"
t.text "body"
t.bigint "content_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["content_id"], name: "index_notes_on_content_id"
end
add_foreign_key "notes", "contents"
end
Are you sure that content is ActiveRecord object? It looks like it is instance of ActiveSupport SafeBuffer.
I'm developing a app on Rails to sell some products, with a table Users, a table Products and a table Reviews, where the users can write their own reviews on a given product; Now i'm starting to implement the payment system, starting with the monetize gem, but after i added the price field to the Product table and run rails db:seed, causes conflict with the Reviews table... Some advice needed. Present code goes like this:
product.rb
class Product < ApplicationRecord
has_one_attached :photo
has_many :reviews, dependent: :nullify
monetize :price_cents
include PgSearch
pg_search_scope :search_by_full_name, against: [:name]
end
review.rb
class Review < ApplicationRecord
belongs_to :user
belongs_to :product
end
schema.rb
ActiveRecord::Schema.define(version: 2020_11_11_190245) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.bigint "record_id", null: false
t.bigint "blob_id", null: false
t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
end
create_table "active_storage_blobs", force: :cascade do |t|
t.string "key", null: false
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
t.bigint "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "price_cents", default: 0, null: false
end
create_table "reviews", force: :cascade do |t|
t.text "description"
t.bigint "user_id", null: false
t.bigint "product_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["product_id"], name: "index_reviews_on_product_id"
t.index ["user_id"], name: "index_reviews_on_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.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "first_name"
t.string "last_name"
t.string "phone_number"
t.string "address"
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
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "reviews", "products"
add_foreign_key "reviews", "users"
end
Sometimes the error goes like this
"PG::NotNullViolation: ERROR: null value in column "product_id" violates not-null constraint"
Thanks for the help
Hi I´m learning to use ActiveAdmin by building an rails App.
I've a products and a category model which are related Product belongs to category.
In the Admin Panel I can create Categories and Products
When I´m creating new product and assigning it to a category I have created the product always ends up belonging to a category called "No Category"
this "No category" option is supposed to be default if no other category is assigned to the product.
I´m not sure why this is happening since I can choose from multiple categories that I've created.
this is my product model
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :page
validates :title, :description, presence: true
validates :price_usd, :price_isl, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
has_attached_file :image, styles: { medium: "500x500#", thumb: "100x100#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end
and this is my category.rb model
class Category < ActiveRecord::Base
has_many :products
end
And here is a copy of my Schema.rb
ActiveRecord::Schema.define(version: 20160826161114) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_id", null: false
t.string "resource_type", null: false
t.integer "author_id"
t.string "author_type"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree
add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree
add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree
create_table "admin_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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true, using: :btree
add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true, using: :btree
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "pages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "category_id", default: 5
end
add_index "pages", ["category_id"], name: "index_pages_on_category_id", using: :btree
create_table "products", force: :cascade do |t|
t.string "title"
t.string "image"
t.text "description"
t.decimal "price_usd"
t.decimal "price_isl"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "category_id", default: 4
end
add_index "products", ["category_id"], name: "index_products_on_category_id", using: :btree
add_foreign_key "pages", "categories"
add_foreign_key "products", "categories"
end
I've built a rails app and on pushing it up to heroku and running heroku run rake db:migrate i receive the error:
Migrating to CreateFollowingRelationships (20160615113231)
(0.4ms) BEGIN
== 20160615113231 CreateFollowingRelationships: migrating =====================
-- create_table(:following_relationships)
(7.1ms) CREATE TABLE "following_relationships" ("id" serial primary key, "follower_id" integer, "followed_user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_39102b381e"
FOREIGN KEY ("follower_id")
REFERENCES "followers" ("id")
, CONSTRAINT "fk_rails_048c8f7cd9"
FOREIGN KEY ("followed_user_id")
REFERENCES "followed_users" ("id")
)
(0.5ms) ROLLBACK
(0.5ms) SELECT pg_advisory_unlock(2837140123622957145)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "followers" does not exist
: CREATE TABLE "following_relationships" ("id" serial primary key, "follower_id" integer, "followed_user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_39102b381e"
FOREIGN KEY ("follower_id")
REFERENCES "followers" ("id")
, CONSTRAINT "fk_rails_048c8f7cd9"
FOREIGN KEY ("followed_user_id")
REFERENCES "followed_users" ("id")
)
The relationship I have setup is for users to follow users and be followed. It works perfectly in development. This is the first time i've had this error and can't find a solution. Please see the rest of my code below.
db/schema.rb
ActiveRecord::Schema.define(version: 20160618122126) do
create_table "chats", force: :cascade do |t|
t.integer "user_id"
t.string "title"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "profile_id"
t.index ["profile_id"], name: "index_chats_on_profile_id"
t.index ["user_id"], name: "index_chats_on_user_id"
end
create_table "comments", force: :cascade do |t|
t.integer "profile_id"
t.integer "chat_id"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["chat_id"], name: "index_comments_on_chat_id"
t.index ["profile_id"], name: "index_comments_on_profile_id"
end
create_table "following_relationships", force: :cascade do |t|
t.integer "follower_id"
t.integer "followed_user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["followed_user_id"], name: "index_following_relationships_on_followed_user_id"
t.index ["follower_id"], name: "index_following_relationships_on_follower_id"
end
create_table "locations", force: :cascade do |t|
t.string "locationable_type"
t.integer "locationable_id"
t.string "suburb"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "address"
t.string "state"
t.string "country"
t.string "postcode"
t.float "latitude"
t.float "longitude"
t.index ["locationable_type", "locationable_id"], name: "index_locations_on_locationable_type_and_locationable_id"
t.index ["user_id"], name: "index_locations_on_user_id"
end
create_table "orders", force: :cascade do |t|
t.integer "buyer_id"
t.integer "seller_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.integer "profile_id"
t.integer "user_id"
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["profile_id"], name: "index_posts_on_profile_id"
t.index ["user_id"], name: "index_posts_on_user_id"
end
create_table "profiles", force: :cascade do |t|
t.integer "user_id"
t.text "bio"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_profiles_on_user_id"
end
create_table "tutoring_relationships", force: :cascade do |t|
t.integer "tutor_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "tutee_id"
t.index ["tutee_id"], name: "index_tutoring_relationships_on_tutee_id"
t.index ["tutor_id"], name: "index_tutoring_relationships_on_tutor_id"
end
create_table "users", force: :cascade do |t|
t.string "email", null: false
t.string "password_digest", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "username"
t.boolean "tutor", default: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["username"], name: "index_users_on_username", unique: true
end
create_table "votes", force: :cascade do |t|
t.string "votable_type"
t.integer "votable_id"
t.string "voter_type"
t.integer "voter_id"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
t.index ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"
end
end
models/following_relationship.rb
class FollowingRelationship < ApplicationRecord
belongs_to :follower, class_name: 'User'
belongs_to :followed_user, class_name: 'User'
end
models/user.rb
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
has_many :chats
validates :email, presence: true, uniqueness: true
validates :password_digest, presence: true
has_many :follower_relationships,
foreign_key: :followed_user_id,
class_name: 'FollowingRelationship'
has_many :followers, through: :follower_relationships
has_many :followed_user_relationships,
foreign_key: :follower_id,
class_name: "FollowingRelationship"
has_many :followed_users, through: :followed_user_relationships
has_many :tutee_relationships,
foreign_key: :tutor_id,
class_name: 'TutoringRelationship'
has_many :tutees, through: :tutee_relationships
has_many :tutor_relationships,
foreign_key: :tutee_id,
class_name: 'TutoringRelationship'
has_many :tutors, through: :tutor_relationships
def following? user
followed_user_ids.include?(user.id)
end
def is_connected? user
tutee_ids.include?(user.id)
end
end
Please excuse the messy model, it would usually be in a helper method but for this post it's here. If anyone has any ideas please let me know! Thanks