How to add primary key to Rails? - ruby-on-rails

I'm trying to make an e-commerce website type thing using Rails. So I've made my models for it. My problem is how to make a particular element a primary key?
create_table "bookmarks", :primary_key => bk_id force: :cascade do |t|
t.string "bk_name"
t.string "size"
t.string "brand"
t.string "product_id"
t.integer "mrp"
t.text "colour"
t.integer "stock"
t.integer "discount"
t.text "bk_description"
t.integer "bk_id", primary:true
t.integer "cart_unit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
This is a portion of the schema.rb file. Is the way I've marked bookmark id as the primary key correct? Also, after making these changes, I ran rails db:migrate command and the primary key portion disappears and it becomes like this-
create_table "bookmarks",force: :cascade do |t|
t.string "bk_name"
t.string "size"
t.string "brand"
t.string "product_id"
t.integer "mrp"
t.text "colour"
t.integer "stock"
t.integer "discount"
t.text "bk_description"
t.integer "bk_id"
t.integer "cart_unit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
I don't understand why this happened and why those changes I made (I did save the file after editing) just disappeared. Can someone explain this to me? Also, I'd like to mention that I'm learning Ruby on Rails so...please be gentle with me. :P

In your migration file:
create_table :bookmarks, :primary_key => :bk_id do |t|
...
t.integer :bk_id
...
end
Do not forget to indicate it in your Model too:
class Bookmarks < ActiveRecord::Base
self.primary_key = 'bk_id'
end

Assuming it’s Rails4+, you might do:
create_table :bookmarks, force: :cascade do |t|
...
t.integer :bk_id, primary_key: true
...
end
In Rails3 you just put an additional statement after:
create_table "bookmarks", force: :cascade do |t|
...
t.integer "bk_id"
...
end
execute "ALTER TABLE bookmarks ADD PRIMARY KEY (bk_id);"

Don't change content of schema.rb file. This content will be auto generated from your migrate files. Try find your create bookmarks migrate file and add :primary_key => bk_id to it.
File: db/migrate/xxxxxxxxxx_create_bookmarks.rb
(xxxxxxxxx is a timestamp)
Help it helps.

Related

Redirect to edit page if id is present in rails

I am trying to redirect a page, I want to check if params student_id and pre_writings table's student_id match and if it matches the I want to redirect it to edit page.
my pre-writings schema:
create_table "pre_writings", force: :cascade do |t|
t.integer "student_id"
t.integer "classroom_id"
t.integer "task_id"
t.text "q1"
t.string "q1answer"
t.text "q2"
t.string "q2answer"
t.text "q3"
t.string "q3answer"
t.text "q4"
t.string "q4answer"
t.text "q5"
t.string "q5answer"
t.text "q6"
t.string "q6answer"
t.text "q7"
t.string "q7answer"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
And the link I am sending the params with student_id
<a href="/<%= #tasksname.downcase %>/new?student_id=<%= student_id=element.id %>&task_id=<%= assessment.task.id %> ">
In the appropriate method in your controller, add:
redirect_to <your edit page path> if params[:student_id].present?
However, I would like to echo what other commenters have said, I do not think you are following Rails best practices. If you follow the "Rails Way" of doing things, this should be easier. We will need more information about your model setup and what you are trying to do to help you refactor your code to follow Rails best practices.

ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "categories" does not exist

I am building a small rails app. When, I run heroku run rake db:migrate, I get this error
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "categories" does not exist
: CREATE TABLE "habits" ("id" serial primary key, "name" character varying, "description" character varying, "category_id" integer, "user_id" integer, "created_at
" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_23642321ab"
FOREIGN KEY ("category_id")
REFERENCES "categories" ("id")
, CONSTRAINT "fk_rails_541267aaf9"
FOREIGN KEY ("user_id")
REFERENCES "users" ("id")
)
In attempt to solve it, I also added this to inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'category', 'categories'
inflect.plural 'category', 'categories'
end
Which didn't help.
I also looked at few answers on stackoverflow including this, but it didn't help because I am getting this error when I run migration command.
Here is my migration files for categories and habits.
class CreateCategories < ActiveRecord::Migration[5.0]
def change
create_table :categories do |t|
t.string :name
t.timestamps
end
end
end
class CreateHabits < ActiveRecord::Migration[5.0]
def change
create_table :habits do |t|
t.string :name
t.string :description
t.integer :user_id
t.integer :category_id
t.timestamps
end
end
end
Here is my schema.rb
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170612231416) do
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 "comments", force: :cascade do |t|
t.text "description"
t.integer "habit_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "goals", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "goals_habits", force: :cascade do |t|
t.integer "habit_id"
t.integer "goal_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "goals_milestones", force: :cascade do |t|
t.integer "goal_id"
t.integer "milestone_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "habits", force: :cascade do |t|
t.string "name"
t.string "description"
t.integer "user_id"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "milestones", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "milestones_statuses", force: :cascade do |t|
t.integer "milestone_id"
t.integer "status_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "statuses", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "role"
end
end
Not sure what more I am missing!
It seems there is a problem with your migrations. Run this locally to see if they run without a problem: rake db:drop && rake db:create && rake db:migrate
PS: I don't tell you to run rake db:reset because that loads the schema instead of running the migrations.
It kind of seems like your migrations files are the problem. Perhaps try rake db:schema:load instead. I have had similar problems before and it is always because of a column added after the initial migration.
Finally, I just had to destroy my Heroku app and recreate it. That solved this problem. I didn't have much data in my app. So, I could do it. If you have a really good database, I wouldn't suggest it.
To destroy app, heroku apps:destroy
And to create it again, heroku create appname

ActiveModel::MissingAttributeError: can't write unknown attribute `book_id`

I have this problem, but don't know why.
I create models with generator:
bin/rails generate model Book name:string author:string description:text cover:string
bin/rails generate model Episode name:string description:text art:string
ant other...
book.rb
class Book < ApplicationRecord
has_many :episodes
end
episode.rb
class Episode < ApplicationRecord
belongs_to :book
has_many :scenes
end
When in console i try to: book.episodes << episode i had an error: ActiveModel::MissingAttributeError: can't write unknown attribute "book_id"
My schema.rb
ActiveRecord::Schema.define(version: 20170320111956) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "answers", force: :cascade do |t|
t.text "text"
t.string "next_scene"
t.string "next_episode"
t.string "voiceover"
t.integer "end"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "books", force: :cascade do |t|
t.string "name"
t.string "author"
t.text "description"
t.string "cover"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "episodes", force: :cascade do |t|
t.string "name"
t.text "description"
t.string "art"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "scenes", force: :cascade do |t|
t.string "name"
t.text "text"
t.integer "choise"
t.string "next_scene"
t.string "next_episode"
t.string "art"
t.string "music"
t.string "sound_fx"
t.string "voiceover"
t.integer "end"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
In schema i haven't id_book, but why? I also do db:migrate and have error again.
By default, Rails uses the convention of naming the primary as the autogenerated column id. If you wish to specify a different primary key, such as book_id, you could do the following:
class Book < ApplicationRecord
self.primary_key = "book_id"
end

new record in rails console error

A very similar question was already asked, bud I can't solve the problem anyway. I am trying to create a new record in rails console and I get this error:
2.1.2 :001 > subject = Subject.new
Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'simple_cms_development.subjects' doesn't exist: SHOW FULL FIELDS FROM `subjects`
Can somebody please very specifically tell my what should I do?
Here's subject.rb:
class Subject < ActiveRecord::Base
end
and schema.rb:
ActiveRecord::Schema.define(version: 20140617074943) do
create_table "admin_users", force: true do |t|
t.string "first_name", limit: 25
t.string "last_name", limit: 50
t.string "email", default: "", null: false
t.string "username", limit: 25
t.string "password", limit: 40
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "pages", force: true do |t|
t.integer "subject_id"
t.string "name"
t.string "permalink"
t.integer "position"
t.boolean "visible", default: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "pages", ["permalink"], name: "index_pages_on_permalink", using: :btree
add_index "pages", ["subject_id"], name: "index_pages_on_subject_id", using: :btree
create_table "sections", force: true do |t|
t.integer "page_id"
t.string "name"
t.integer "position"
t.boolean "visible", default: false
t.string "content_tipe"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "sections", ["page_id"], name: "index_sections_on_page_id", using: :btree
end
create_subjects.rb:
class CreateSubjects < ActiveRecord::Migration
def up
create_table :subjects do |t|
t.string "name"
t.integer "position"
t.boolean "visible" :default => false
t.timestamps
end
end
def down
drop_table :subjects
end
end
Add a comma in
t.boolean "visible" :default => false`
as in
t.boolean "visible", :default => false`
and then run rake db:migrate
Making sure that config/database.yml file has a valid entry for a database connection on your machine. Look at the development stanza.
More on migrations at guides.rubyonrails.org/migrations.html
More on configuring a database and the database.yml file at
http://edgeguides.rubyonrails.org/configuring.html#configuring-a-database
You need to create a subjects table that defines the attributes you want to persist in the Subject instances.
So say you want title and description. Use this command to create the migration:
rails generate migration subjects title:string description:text
And then run the command
rake db:migrate
Then try your Subject.new command
Alternatively, if you do not want to persist any subject attributes, change the subject class definition to:
class Subject
end

How to display difficult-model view in rails app?

I have such db schema:
Tables:
COUNTRY_DESIGNATIONS
DES_TEXTS
MANUFACTURERS
MODELS
And such relationships:
COUNTRY_DESIGNATIONS has_many MODELS
DES_TEXTS has_many COUNTRY_DESIGNATIONS
MANUFACTURERS has_many MODELS
In rails model all relations and other "things" are written.
And when i select manufactures, I get all it's models. But now I want in these models to select data from COUNTRY_DESIGNATIONS (sure all table relations id's must be equal), and then when select data from COUNTRY_DESIGNATIONS i want to fetch data from DES_TEXTS and display it.
How can i do this? what change in controllers, views? (I were using standart scaffolds)
now i have such view to view models from manufacturer:
- #manufacturer.models.each do |model|
%tr
%p
mod_id
%td= model.MOD_ID
%p
MOD_PCON_START
%td= model.MOD_PCON_START
%p
MOD_PCON_END
%td= model.MOD_PCON_END
= link_to 'Show model', model
and i want to add something like this:
- #manufacturer.models.each do |model|
%tr
%p
...
%td= model.country_des.des_text.FIELD - something like this)
= link_to 'Show model', model
models files:
class CountryDesignation < ActiveRecord::Base
set_table_name "COUNTRY_DESIGNATIONS"
set_primary_key :CDS_ID
belongs_to :des_text
belongs_to :language
has_many :models
end
class DesText < ActiveRecord::Base
set_table_name "DES_TEXTS"
set_primary_key :TEX_ID
has_many :country_designation
has_many :designation
end
class Model < ActiveRecord::Base
set_table_name "MODELS"
set_primary_key :MOD_ID
belongs_to :manufacturer
belongs_to :country_designation
has_many :types
end
dump:
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120418164608) do
create_table "COUNTRY_DESIGNATIONS", :primary_key => "CDS_ID", :force => true do |t|
t.binary "CDS_CTM"
t.integer "CDS_LNG_ID"
t.integer "CDS_TEX_ID"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "DESIGNATIONS", :primary_key => "DES_ID", :force => true do |t|
t.integer "DES_LNG_ID"
t.integer "DES_TEX_ID"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "DES_TEXTS", :primary_key => "TEX_ID", :force => true do |t|
t.text "TEX_TEXT"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "LANGUAGES", :primary_key => "LNG_ID", :force => true do |t|
t.integer "LNG_DES_ID"
t.string "LNG_ISO2"
t.string "LNG_CODEPAGE"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "MANUFACTURERS", :primary_key => "MFA_ID", :force => true do |t|
t.integer "MFA_PC_MFC"
t.integer "MFA_CV_MFC"
t.integer "MFA_AXL_MFC"
t.integer "MFA_ENG_MFC"
t.integer "MFA_ENG_TYP"
t.string "MFA_MFC_CODE"
t.string "MFA_BRAND"
t.integer "MFA_MF_NR"
t.binary "MFA_PC_CTM"
t.binary "MFA_CV_CTM"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "MODELS", :primary_key => "MOD_ID", :force => true do |t|
t.integer "MOD_MFA_ID"
t.integer "MOD_CDS_ID"
t.integer "MOD_PCON_START"
t.integer "MOD_PCON_END"
t.integer "MOD_PC"
t.integer "MOD_CV"
t.integer "MOD_AXL"
t.binary "MOD_PC_CTM"
t.binary "MOD_CV_CTM"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "TYPES", :primary_key => "TYP_ID", :force => true do |t|
t.integer "TYP_CDS_ID"
t.integer "TYP_MMT_CDS_ID"
t.integer "TYP_MOD_ID"
t.binary "TYP_CTM"
t.binary "TYP_LA_CTM"
t.integer "TYP_SORT"
t.integer "TYP_PCON_START"
t.integer "TYP_PCON_END"
t.integer "TYP_KW_FROM"
t.integer "TYP_KW_UPTO"
t.integer "TYP_HP_FROM"
t.integer "TYP_HP_UPTO"
t.integer "TYP_CCM"
t.integer "TYP_CYLINDERS"
t.integer "TYP_DOORS"
t.integer "TYP_TANK"
t.integer "TYP_KV_VOLTAGE_DES_ID"
t.integer "TYP_KV_ABS_DES_ID"
t.integer "TYP_KV_ASR_DES_ID"
t.integer "TYP_KV_ENGINE_DES_ID"
t.integer "TYP_KV_BRAKE_TYPE_DES_ID"
t.integer "TYP_KV_BRAKE_SYST_DES_ID"
t.integer "TYP_KV_FUEL_DES_ID"
t.integer "TYP_KV_CATALYST_DES_ID"
t.integer "TYP_KV_BODY_DES_ID"
t.integer "TYP_KV_STEERING_DES_ID"
t.integer "TYP_KV_STEERING_SIDE_DES_ID"
t.float "TYP_MAX_WEIGHT"
t.integer "TYP_KV_MODEL_DES_ID"
t.integer "TYP_KV_AXLE_DES_ID"
t.integer "TYP_CCM_TAX"
t.float "TYP_LITRES"
t.integer "TYP_KV_DRIVE_DES_ID"
t.integer "TYP_KV_TRANS_DES_ID"
t.integer "TYP_KV_FUEL_SUPPLY_DES_ID"
t.integer "TYP_VALVES"
t.integer "TYP_RT_EXISTS"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "carts", :force => true do |t|
t.integer "customer_id"
t.integer "item_id"
t.integer "amount"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "credit_cards", :force => true do |t|
t.integer "customer_id"
t.string "number"
t.string "nameOfCard"
t.date "expiryDate"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "currencies", :force => true do |t|
t.float "currencyvalue"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "customer_sessions", :force => true do |t|
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "customers", :force => true do |t|
t.string "username"
t.string "crypted_password"
t.string "password_salt"
t.string "persistence_token"
t.string "email"
t.string "skype"
t.integer "ICQ"
t.string "firstname"
t.string "lastname"
t.string "country"
t.string "state"
t.string "city"
t.string "street"
t.string "building"
t.integer "room"
t.string "addressNote"
t.string "dateOfReg"
t.integer "custGroup_id"
t.float "totalBuy"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "order_statuses", :force => true do |t|
t.string "statusname"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "orders", :force => true do |t|
t.integer "basket_id"
t.integer "customer_id"
t.integer "shipping_id"
t.integer "paymentmethod_id"
t.integer "orderstatus_id"
t.datetime "dateoforder"
t.float "totalcost"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "payment_methods", :force => true do |t|
t.string "methodname"
t.boolean "allowed"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "sellers", :force => true do |t|
t.string "username"
t.string "crypted_password"
t.string "password_salt"
t.string "persistence_token"
t.string "email"
t.string "skype"
t.integer "ICQ"
t.string "firstname"
t.string "lastname"
t.string "dateOfReg"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "shippings", :force => true do |t|
t.string "shippingname"
t.float "shippingcost"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "telephone_operators", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "telephones", :force => true do |t|
t.integer "customer_id"
t.integer "operator"
t.integer "number"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "virtual_pay_systems", :force => true do |t|
t.string "name"
t.boolean "active"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "virtual_pays", :force => true do |t|
t.integer "customer_id"
t.string "number"
t.integer "virtualpaysystem_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
The code you have written should mostly work, but there is a subtle error in it:
The belongs_to association uses the singular (as in belongs_to :manufacturer), but for the associationhas_many, you have to use the plural:
class DesText < ActiveRecord::Base
set_table_name "DES_TEXTS"
set_primary_key :TEX_ID
has_many :country_designations
has_many :designations
end
Please ensure that the relevant keys are set in your tables. Here are the rules for you:
Every has_many association (see Rails Guides) needs that the many part has a reference to the one part. In your example: Model needs a reference to CountryDesignation. Rails thinks that your model table includes a column country_designation_id (which it will not find).
Similar for DES_TEXTS and COUNTRY_DESIGNATIONS.
After having corrected that, you should be able to use the following code (only the changed one with the deep access over some objects):
- #manufacturer.models.each do |model|
%tr
%p
...
%td= model.country_designation.des_text.FIELD
= link_to 'Show model', model
This will show inside a loop for each model of the manufacturer the des_text of its country_designation.
But be careful: This is only an example and will only work, if every model has a country designation and every country designation has a des_text.
It is unfortunate that you use an existing db scheme, it makes a lot of things more difficult. I would give you the following advice here:
Migrate to a clean state with names rails suspects.
Test after each migration, if your model conforms to the rules by using the console of Rails. You can start then rails c and type there in commands you think should work.
Your application is a the moment to big and complicated, so I don't think there is a chance to debug it further here ... (sorry, but this is the fourth time I add to my answer, and it looks more like a Rails tutorial now)

Resources