Rails saves value to database beyond limit restriction - ruby-on-rails

I have this schema in Rails 6
create_table "fields", force: :cascade do |t|
t.string "title", limit: 100
t.text "description"
t.string "slug", limit: 20
t.integer "requests"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["slug"], name: "index_fields_on_slug", unique: true
t.index ["title"], name: "index_fields_on_title", unique: true
And inside rails console:
field = Field.new
field.slug = 'a' *25
field.save
And the entry is saved succesfully inside fields table.
Why? I have a limit of 20 for :slug. Shouldn't that fail without validate in the model?

Related

Rails 7 - Undo/Remove a Schema.rb add_foreign_key reference & start over

I have started my project with a Users table and have since migrated to using an Accounts table. In the process I have an old reference to the Users table still in my schema.rb file and I need to remove it and create a new reference, or update the reference.
I am trying to work out a migration that will allow me to do this, however it keeps throwing an error as there's no Users table and when it did exist, it never had an account_id , which you can see referenced in my schema.rb file.
I really just need my schema.rb file to update
"add_foreign_key "likes", "users", column: "account_id"
to
add_foreign_key "likes", "accounts", column: "account_id"
But am finding this impossible to do with a migration without generating an error.
Any suggestions?
ActiveRecord::Schema.define(version: 2022_01_18_013836) do
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", precision: 6
t.datetime "remember_created_at", precision: 6
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "username"
t.string "first_name"
t.string "last_name"
t.index ["email"], name: "index_accounts_on_email", unique: true
t.index ["reset_password_token"], name: "index_accounts_on_reset_password_token", unique: true
end
create_table "likes", force: :cascade do |t|
t.integer "account_id", null: false
t.integer "product_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["account_id"], name: "index_likes_on_account_id"
t.index ["product_id"], name: "index_likes_on_product_id"
end
create_table "products", force: :cascade do |t|
t.string "product_name"
t.string "product_category"
t.string "product_type"
t.string "product_image"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.text "product_description"
t.string "product_country"
end
add_foreign_key "likes", "products"
add_foreign_key "likes", "users", column: "account_id"
end
Best way to resolve this is to create a migration that adds users back with only account_id then remove the foreign key, and drop the user table again.
Should be doable in 1 migration, however I went about it as follows.
I ended up creating a new Users table with just an account_id:integer
Created a migration to remove_foreign_key
Then created a migration to then drop that Users table again.
Schema file is looking correct now and I have all the migrations to trace my changes.

Active Admin No Method error in foreign key relationship

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.

Rails update or delete on table "products" violates foreign key constraint

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

Why will a rake file used to seed a datbase not work due to foreign key constraints in Ruby on Rails?

I have created a dummy travel agency with Rails 6 and I am trying to use a rake file to seed data for ships, crusies and customer details etc.
The file: ships.rake looks like this:
namespace :ships do
desc "TODO"
task seed_cabins: :environment do
CreditCard.destroy_all
Address.destroy_all
Customer.destroy_all
Cruise.destroy_all
Ship.destroy_all
p "tables emptied"
5.times do |index|
Ship.create!(name: Faker::Coffee.blend_name, tonnage: Faker::Number.within(range: 10000..100000))
end
p "ships created"
# create cabins for each ship
ships = Ship.all
ships.each do |ship|
5.times do |index|
Cabin.create!(
ship_id: ship.id,
name: "Suite #{index+1}",
beds: Faker::Number.between(from: 1, to: 3),
deck: Faker::Number.between(from: 1, to: 3)
)
end
end
p "Cabins created"
ships = Ship.all
ships.each do |ship|
2.times do |index|
Cruise.create!(
ship_id: ship.id,
name: Faker::Hacker.adjective.capitalize + " " +Faker::Hacker.noun.capitalize+" Cruise"
)
end
end
#create customers
3.times do |index |
Customer.create!(
first_name:Faker::Name.first_name,
last_name:Faker::Name.last_name,
has_good_credit: true,
paid: false
)
end
#give each customer an addresses and credit card
customers = Customer.all
customers.each do | customer|
Address.create!(
street:Faker::Address.street_address,
city:Faker::Address.city,
postcode:Faker::Address.postcode,
customer_id: customer.id
)
year = [2020, 2021,2022, 2023]
organisations =["American Express", "MasterCard", "Visa"]
CreditCard.create!(
customer_id:customer.id,
number:Faker::Number.number(12),
exp_date:year.sample.to_s + "/" + Faker::Number.between(1,12).to_s,
name_on_card: customer.first_name + " " + customer.last_name,
organisation: organisations.sample.to_s
)
end
p "customers created"
end
end
The database schema looks like this:
ActiveRecord::Schema.define(version: 2020_10_27_221059) do
create_table "addresses", force: :cascade do |t|
t.string "street"
t.string "city"
t.string "postcode"
t.integer "customer_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["customer_id"], name: "index_addresses_on_customer_id"
end
create_table "cabins", force: :cascade do |t|
t.string "name"
t.integer "beds"
t.integer "deck"
t.integer "ship_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["ship_id"], name: "index_cabins_on_ship_id"
end
create_table "credit_cards", force: :cascade do |t|
t.string "number"
t.string "exp_date"
t.string "name_on_card"
t.string "organisation"
t.integer "customer_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["customer_id"], name: "index_credit_cards_on_customer_id"
end
create_table "cruises", force: :cascade do |t|
t.string "name"
t.integer "ship_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["ship_id"], name: "index_cruises_on_ship_id"
end
create_table "customers", force: :cascade do |t|
t.string "last_name"
t.string "first_name"
t.integer "has_good_credit"
t.boolean "paid"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "harbours", force: :cascade do |t|
t.string "name"
t.string "country"
t.string "lat"
t.string "long"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "ships", force: :cascade do |t|
t.string "name"
t.integer "tonnage"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
add_foreign_key "addresses", "customers"
add_foreign_key "cabins", "ships"
add_foreign_key "credit_cards", "customers"
add_foreign_key "cruises", "ships"
end
Essentially, I am just try to run the command: rake ships:seed_cabins and try to generate the data fresh. However, I keep getting the following error:
rake aborted!
ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed
/home/jonathon/Projects/waad/RailsApps/travelagent/lib/tasks/ships.rake:8:in `block (2 levels) in <main>'
Caused by:
SQLite3::ConstraintException: FOREIGN KEY constraint failed
/home/jonathon/Projects/waad/RailsApps/travelagent/lib/tasks/ships.rake:8:in `block (2 levels) in <main>'
Tasks: TOP => ships:seed_cabins
(See full trace by running task with --trace)
I am aware the order of when the tables are destroyed is an issue and the current order is the closest I can get to the file working. it seems to be the Ship.destroy_all line that is the issue because when I remove it and run the file it runs with no issues!
However, as far as I can see there would be no constraints left on that database once the other tables are cleared that would prevent Ship from being deleted?
If anyone could point me in the right direction I would be very grateful.
You missed destroying the cabins, which are still referencing the ships as foreign key. Hence the foreign key constraint is kicking in.
On a side note, you can make your life easier by adding dependent: :destroy in your associations. For example, in your Ship model, you would add,
class Ship < ApplicationRecord
has_many :cabins, dependent: :destroy
end
Since a cabin doesn't make sense without the corresponding ship. What this will do is, whenever a Ship instance is destroyed, it will destroy the related cabins as well.

Can't order when the field name is "date" in Rails?

I have a Game model with fields start_time and date (amongst others). #tournament.games.order('start_time asc') works, but #tournament.games.order('date asc') doesn't work. t.games.order("date asc") and t.games.order("date desc") produce the same order. Why is that?
Here's my schema for games:
create_table "games", force: :cascade do |t|
t.bigint "tournament_id", null: false
t.string "team_one_type", null: false
t.bigint "team_one_id", null: false
t.string "team_two_type", null: false
t.bigint "team_two_id", null: false
t.bigint "field_id", null: false
t.date "date"
t.datetime "start_time"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["field_id"], name: "index_games_on_field_id"
t.index ["team_one_type", "team_one_id"], name: "index_games_on_team_one_type_and_team_one_id"
t.index ["team_two_type", "team_two_id"], name: "index_games_on_team_two_type_and_team_two_id"
t.index ["tournament_id"], name: "index_games_on_tournament_id"
end
This could be just because you search only by the date (and the records with the same date will not change), however, if you sort by DateTime every record will sort (including the records in the same date).

Resources