I am working on a simple support ticket system , however I'm getting a weird error. Here is the error :
ActiveModel::MissingAttributeError: can't write unknown attribute division_id
and here is the code :
user.rb:
class User < ApplicationRecord
belongs_to :division
has_many :teckets
has_many :teckets , through: :user_tecket
has_secure_password
end
division.rb:
class Division < ApplicationRecord
has_many :users
has_many :users, through: :user_division
has_many :teckets
has_many :teckets, through: :teckets_divisions
end
tecket.rb :
class Tecket < ApplicationRecord
belongs_to :division
belongs_to :user
has_one :status
has_one :status, through: :tecket_statuses
end
teckets_division.rb :
class TecketsDivision < ApplicationRecord
belongs_to :tecket
belongs_to :division
end
schema.rb:
ActiveRecord::Schema.define(version: 20171001063612) do
create_table "divisions", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "replies", force: :cascade do |t|
t.string "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "statuses", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tecket_replies", force: :cascade do |t|
t.integer "tecket_id"
t.integer "reply_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tecket_statuses", force: :cascade do |t|
t.integer "tecket_id"
t.integer "status_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "teckets", force: :cascade do |t|
t.string "title"
t.string "content"
t.string "platform"
t.string "version"
t.string "client_anme"
t.string "client_phone"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "teckets_divisions", force: :cascade do |t|
t.integer "tecket_id"
t.integer "division_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "user_divisions", force: :cascade do |t|
t.integer "user_id"
t.integer "division_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "user_teckets", force: :cascade do |t|
t.integer "user_id"
t.integer "tecket_id"
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 "passwrod"
t.string "password_digest"
t.integer "division_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
I get the error when I try to create a user from the console
Edit : I have added the schema.rb file as requested
either remove the division_id from the user table and has_many :users from divisions model
or (and the simpler approach),
remove user_divisions join table and this line from division model:
has_many :users, through: :user_division
also - You have a lot of join tables it seems, but I don't see the need for their use. You could direct relate them in most of the cases you have shown.
Related
I am still relatively new to Active Record and have a (hopefully simple) question.
I have four tables Recipes(Name of recipe), Food(lettuce, Pepper), Units(oz, tbsp), and Ingredients(Id's of the other tables and the numeric quantity).
What I'd like to do is something like this Recipes.Ingredients and get "Peppered Lettuce, 5 tbsp pepper, 10 oz Lettuce".
How would I accomplishes that with the following schema. And if not possible with this schema what should I build in its place.
The Schema looks like this:
create_table "food", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "ingredients", force: :cascade do |t|
t.bigint "recipes_id"
t.bigint "units_id"
t.bigint "food_id"
t.decimal "quantity"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["food_id"], name: "index_ingredients_on_food_id"
t.index ["recipes_id"], name: "index_ingredients_on_recipes_id"
t.index ["units_id"], name: "index_ingredients_on_units_id"
end
create_table "recipes", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
end
create_table "units", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
so what I understand from your question is you want to get results like:
Peppered Lettuce, 5 tbsp pepper, 10 oz Lettuce in which Peppered Lettuce is Recipe name, and Pepper and Lettuce are Food items with numeric quantities of ingredients.
You don't need 4 tables to obtain this result. You only need 3. Food, Recipe and an in-between table for their many-to-many association.
Recipe can have multiple Food items in it and 1 Food item can be a part of multiple Recipe objects. So Food and Recipe model will have a many-to-many association. And for this kind of association, you need another table. You can name it Foods_Recipes or simply Ingredients.
Your Ingredient model will then have a food_id,recipe_id,numeric_quantity and unit_type
The Schema would look like this:
create_table "foods", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "ingredients", force: :cascade do |t|
t.bigint "recipe_id"
t.bigint "food_id"
t.decimal "quantity"
t.string "unit_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["food_id"], name: "index_ingredients_on_food_id"
t.index ["recipe_id"], name: "index_ingredients_on_recipe_id"
end
create_table "recipes", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
end
Your models would look like this:
Food model:
class Recipe < ApplicationRecord
has_many :ingredients
has_many :foods,through: :ingredients
end
Ingredient model:
class Ingredient < ApplicationRecord
belongs_to :recipe
belongs_to :food
end
Food model:
class Food < ApplicationRecord
has_many :ingredients
has_many :recipes,through: :ingredients
end
I have 2 tables named : order_items and orders in schema. Following is sample of my schema
create_table "orders", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "token"
t.decimal "sub_total"
t.string "mobile"
t.string "address"
and
create_table "order_items", force: :cascade do |t|
t.integer "order_id", null: false
t.integer "item_id", null: false
t.integer "quantity", null: false
t.decimal "price", precision: 15, scale: 2, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
For Models,
order.rb
has_many :order_items
order_item.rb
belongs_to :order
belongs_to :item
I thought I would have been able to get Order.orderitem.quantity with this association, but not able to get it. I get error as undefined method 'orderitems' for nil:NilClass
try Order.first.order_items
this will return all the order items for first order
then you can loop through them
Order.first.order_items.each do |item|
item.quantity
....
end
or take the item out with index
items = Order.first.order_items
items[0].quantity
I have the following models:
User:
User
has_and_belongs_to_many :user_jobs, foreign_key: "user_id", class_name: "Job"
has_many :jobs, through: :locations
has_many :customers, through: :locations
has_and_belongs_to_many :locations
Location:
Location
has_and_belongs_to_many :users
has_and_belongs_to_many :customers
has_many :jobs
Customer:
Customer
has_many :jobs, dependent: :destroy
has_and_belongs_to_many :locations
Job:
Job
belongs_to :customer
belongs_to :location
has_and_belongs_to_many :users
Here is my Schema.rb file
# 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: 20180308214356) do
create_table "accounts", force: :cascade do |t|
t.string "name"
t.text "company_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "stripe_publishable_key"
t.text "stripe_account_id"
t.text "twilio_account_sid"
t.text "twilio_auth_token"
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "location_id"
t.index ["location_id"], name: "index_categories_on_location_id"
end
create_table "customers", force: :cascade do |t|
t.string "first_name"
t.string "middle_initial"
t.string "last_name"
t.datetime "updated_at", null: false
t.integer "account_id"
t.text "stripe_customer_id"
t.index ["account_id"], name: "index_customers_on_account_id"
end
create_table "customers_locations", id: false, force: :cascade do |t|
t.integer "location_id", null: false
t.integer "customer_id", null: false
end
create_table "drafts", force: :cascade do |t|
t.string "phone_one"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "jobs", force: :cascade do |t|
t.date "date"
t.integer "time"
t.boolean "time_sensitive"
t.text "address_line_one"
t.text "address_line_two"
t.string "city"
t.string "state"
t.string "zip"
t.text "special_instructions"
t.text "description"
t.text "work_completed"
t.text "billing_information"
t.text "notes"
t.string "status"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_id"], name: "index_jobs_on_customer_id"
t.index ["location_id"], name: "index_jobs_on_location_id"
end
create_table "jobs_users", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "job_id", null: false
end
create_table "locations", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "account_id"
t.index ["account_id"], name: "index_locations_on_account_id"
end
create_table "locations_users", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "location_id", 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.integer "location_id"
t.integer "account_id"
t.integer "role_id"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["location_id"], name: "index_users_on_location_id"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["role_id"], name: "index_users_on_role_id"
end
end
With this model structure I can query the jobs model in two different ways. First user.user_jobs and user.jobs. Both of these queries return two different result sets. I need to be able to do the same thing with the customers. I can currently query user.customers but I do not know what syntax I should use to make user.user_customers work so that the query joins with the users' related jobs and then grabs the customers related to those jobs. My current query joins the users' locations and grabs the customers associated with those locations. Thanks in advance!
has_many :user_job_customers, through: :user_jobs, source: 'customers'
has_many :location_customers, through: :locations, source: 'customers'
I guess you need :source option
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
I'm rails begginer.
how to load database that has following condition.
I want show lecture list that has order by comment.created_at DESC
schema.rb
create_table "comments", force: :cascade do |t|
t.text "content"
t.integer "user_id"
t.integer "lecture_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likedcount", default: 0
end
create_table "lectures", force: :cascade do |t|
t.string "subject"
t.string "professor"
t.string "major"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "uptachi", default: 0
t.integer "hatachi", default: 0
end
lecture.rb
has_many :comments
comment.rb
belongs_to: lectures
You need to write it as:
has_many :comments, -> { order("comments.created_at DESC") }
As per the OP's comment, it seems, what he want is a named scope. Like,
scope :order_by_comments, -> { joins(:comments).order("comments.created_at DESC") }