Im creating an online retail store. Im trying to create a Category List. I have been able to make a category list but i need subcategories in a nested tree like structure.
Such as the following:
Mobile Phones
Apple
HTC
Samsung
Laptops
Sony
Apple
I have tried for 8 hours now and just keep getting stuck.
Im really stuck.
I tried Ancestry Gem.
How would you go about doing this in detail, even step by step would be great?
There are some tutorials but none that i can find that are directly show what im trying to do.
My Database schema.rb as requested.
ActiveRecord::Schema.define(version: 20150721095122) do
create_table "categories", force: :cascade do |t|
t.string "name"
t.string "ancestry"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "categories", ["ancestry"], name: "index_categories_on_ancestry"
create_table "items", force: :cascade do |t|
t.string "title"
t.decimal "price"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
end
add_index "items", ["user_id", "created_at"], name: "index_items_on_user_id_and_created_at"
add_index "items", ["user_id"], name: "index_items_on_user_id"
create_table "users", force: :cascade do |t|
t.string "username"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.string "reset_digest"
t.string ">"
t.datetime "reset_sent_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.text "description"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
end
You can also try using awesome_nested_set gem that supports nesting, and it has nice documentation, and a list of all methods
Related
When I run:
rails db:seed
in the command line, I get the following error:
ActiveModel::UnknownAttributeError: unknown attribute 'name' for Review..........................................................
I also get the same error when I run:
rails db:seed
seeds.rb
movie = Movie.find_by(title: 'Iron Man')
movie.reviews.create!(name: "Roger Ebert", stars: 3, comment: "I laughed, I cried, I spilled my popcorn!")
movie.reviews.create!(name: "Gene Siskel", stars: 5, comment: "I'm a better reviewer than he is.")
movie.reviews.create!(name: "Peter Travers", stars: 4, comment: "It's been years since a movie superhero was this fierce and this funny.")
movie = Movie.find_by(title: 'Superman')
movie.reviews.create!(name: "Elvis Mitchell", stars: 5, comment: "It's a bird, it's a plane, it's a blockbuster!")
Genre.create!(name: "Action")
Genre.create!(name: "Comedy")
Genre.create!(name: "Drama")
Genre.create!(name: "Romance")
Genre.create!(name: "Thriller")
Genre.create!(name: "Fantasy")
Genre.create!(name: "Documentary")
Genre.create!(name: "Adventure")
Genre.create!(name: "Animation")
Genre.create!(name: "Sci-Fi")
Here is my schema filee [sic]:
ActiveRecord::Schema.define(version: 20181218222845) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "characterizations", force: :cascade do |t|
t.bigint "movie_id"
t.bigint "genre_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["genre_id"], name: "index_characterizations_on_genre_id"
t.index ["movie_id"], name: "index_characterizations_on_movie_id"
end
create_table "favorites", force: :cascade do |t|
t.bigint "movie_id"
t.bigint "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["movie_id"], name: "index_favorites_on_movie_id"
t.index ["user_id"], name: "index_favorites_on_user_id"
end
create_table "genres", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "movies", force: :cascade do |t|
t.string "title"
t.string "rating"
t.decimal "total_gross"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "description"
t.date "released_on"
t.string "cast"
t.string "director"
t.string "duration"
t.string "image_file_name", default: ""
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "main_image"
t.string "slug"
end
create_table "reviews", force: :cascade do |t|
t.integer "stars"
t.text "comment"
t.bigint "movie_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.index ["movie_id"], name: "index_reviews_on_movie_id"
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.string "username"
t.boolean "admin", default: false
end
add_foreign_key "characterizations", "genres"
add_foreign_key "characterizations", "movies"
add_foreign_key "favorites", "movies"
add_foreign_key "favorites", "users"
add_foreign_key "reviews", "movies"
end
Your reviews table does not have a name column, which is what Rails is telling you.
I don’t know how your app works, but I do see a user_id column on the reviews table, and the users table has a name column, so I imagine you need to create a user using that name attribute, and then pass the user into the review that you’re creating.
Without seeing your Review and User model, I can’t speak for sure.
At a minimum, you'll need to create a migration & run it to add the name field to your reviews table:
rails generate migration AddNameToReviews name:string
rails db:migrate
This should fix your reported error.
In my rails app, I have a User who has many Companies and belongs to a Company. I would like to migrate effectively to a situation where a User has only one Company and still belongs to Company. Is it enough to change the line of code in User.rb to has_one :company
I have already made sure that in my database, all users have just one company. I would like to know the most effective way to complete the migration. This is my sample code for Company.rb belongs_to :user .
For the company create action, i have
def create
#company = Company.new(company_params)
#company.user = current_user
preview_company
end
This is my database schema
create_table "companies", force: :cascade do |t|
t.string "name"
t.text "description"
t.string "website"
t.string "location"
t.string "address"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.string "photo"
t.string "logo"
t.index ["user_id"], name: "index_companies_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.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.boolean "admin", default: false, 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
I used the rails globalize and I18n gem. But now I can't sort my model. Can you guys help?
I tried adding a new index, but I'm not entirely familiar with indexing.
Controller.rb
def index
#foods = Food.all.order(:name)
add_breadcrumb "index", foods_path
end
Schema
create_table "food_translations", force: :cascade do |t|
t.integer "food_id", null: false
t.string "locale", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "bio"
end
add_index "food_translations", ["food_id"], name: "index_food_translations_on_food_id", using: :btree
add_index "food_translations", ["locale"], name: "index_food_translations_on_locale", using: :btree
add_index "food_translations", ["name"], name: "index_food_translations_on_name", using: :btree
create_table "foods", force: :cascade do |t|
t.string "address"
t.string "phone"
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.string "yelp"
t.string "youtube"
end
Yes, you will need a join. If you do not have a model for the translation, you could just use .joins for your finder. Like:
Food.joins('INNER JOIN food_translations ON foods.id=food_translations.food_id')
.order('food_translations.name').where('food_translations.locale=xxx')
ps: I wonder why you do not have a index on "food_id" AND "locale" which should be uniq. In your case you can have two or more translations for 1 food in the same language.
In my Ruby on Rails application I have a cinema system and am trying to show only show times for films that are either in the future or today (so not in the past).
I am trying to do this in my _form.html.erb in a drop down menu:
<%= f.grouped_collection_select :showing_id, live_films.order(:title), :showings, :title, :id, :showing_times %>
Where live_films is the method in application_controller.rb:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :active_menu, :live_films
def live_films
Film.includes(:showings).where('showings.show_date > ?', Date.current.beginning_of_day)
end
end
But I get this error:
ActiveRecord::StatementInvalid in Bookings#new
SQLite3::SQLException: no such column: showings.show_date: SELECT "films".* FROM "films" WHERE (showings.show_date > '2015-02-20 00:00:00.000000') ORDER BY "films"."title" ASC
My db/schema:
ActiveRecord::Schema.define(version: 20150219091141) do
create_table "bookings", force: :cascade do |t|
t.integer "user_id"
t.integer "showing_id"
t.integer "seat_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "categories", force: :cascade do |t|
t.string "genre"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "certificates", force: :cascade do |t|
t.string "age_rating"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "certificate_img_url"
end
create_table "films", force: :cascade do |t|
t.string "title"
t.string "synopsis"
t.string "director"
t.string "cast1"
t.string "cast2"
t.string "cast3"
t.date "release_date"
t.string "warnings"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_url"
t.string "certificate_id"
t.integer "category_id"
t.integer "hours"
t.integer "minutes"
t.string "video_url"
end
create_table "screens", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "seats", force: :cascade do |t|
t.string "row_letter"
t.integer "row_number"
t.integer "screen_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "showings", force: :cascade do |t|
t.date "show_date"
t.time "show_time"
t.integer "film_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "screen_id"
end
add_index "showings", ["film_id"], name: "index_showings_on_film_id"
create_table "users", force: :cascade do |t|
t.string "password_digest"
t.string "role"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "first_name"
t.string "last_name"
t.string "house_no"
t.string "street"
t.string "town"
t.string "postcode"
t.string "email"
end
The column name show_date is correct as is the table name showings but for some reason it isn't working.
Can someone please help?
Here is the solution:
Film.joins(:showings).where('showings.show_date > ?', Date.current.beginning_of_day).preload(:showings)
The more i read about foreign keys in rails i am getting more and more confused. In a post i read that its sufficient to add belongs_to and has_many/has_one in respective model file to getting things done. But again in another post I read that the index should be added to reference another table. Suppose There is writers table and book table in dbms while creating Books table we have to add
FOREIGN KEY (writers_Id) REFERENCES Writers(Id)
but in rails we in writer model we add has_many :book an in book model we add belongs_to :writer is both are equivalent ?
If both are equivalent then why we add index such as
add_index :books, :writer_id
I have project on which I am working on it has users has one personal information, academic information, application and rank. Also there is subject_streams which have streams and streams have cutoffs. Finally there is category which is independent. I dont know if i modeled data correctly but in the schema.rb am I doing correctly what i have said ?
ActiveRecord::Schema.define(version: 20140713133617) do
create_table "academics", force: true do |t|
t.integer "user_id"
t.integer "tenth_roll", default: 0
t.integer "tenth_year_pass", default: 2000
t.decimal "tenth_marks_percent", precision: 10, scale: 2, default: 40.0
t.string "tenth_board"
t.integer "hs_roll", default: 0
t.integer "hs_year_pass", default: 2002
t.decimal "hs_marks_percent", precision: 10, scale: 2, default: 40.0
t.string "hs_board"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "calculated_marks"
t.string "sub1"
t.integer "sub1_marks"
t.string "sub2"
t.integer "sub2_marks"
t.string "sub3"
t.integer "sub3_marks"
t.string "sub4"
t.integer "sub4_marks"
t.string "sub5"
t.integer "sub5_marks"
t.string "sub6"
t.integer "sub6_marks"
t.string "sub7"
t.integer "sub7_marks"
t.string "sub8"
t.integer "sub8_marks"
t.string "sub9"
t.integer "sub9_marks"
t.string "sub10"
t.integer "sub10_marks"
t.integer "subject_streams_id"
end
add_index "academics", ["user_id"], name: "index_academics_on_user_id", unique: true, using: :btree
create_table "applications", force: true do |t|
t.integer "user_id"
t.integer "stream_id"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "verified", default: false
end
add_index "applications", ["user_id"], name: "index_applications_on_user_id", unique: true, using: :btree
create_table "categories", force: true do |t|
t.string "category"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "cutoffs", force: true do |t|
t.integer "stream_id"
t.integer "category_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "cutoff_marks"
end
add_index "cutoffs", ["stream_id"], name: "index_cutoffs_on_stream_id", using: :btree
create_table "personals", force: true do |t|
t.integer "user_id"
t.date "date_of_birth"
t.string "gender"
t.string "blood_group"
t.string "fathers_name"
t.string "mothers_name"
t.text "address_present"
t.datetime "created_at"
t.datetime "updated_at"
t.string "first_name"
t.string "middle_name"
t.string "last_name"
t.integer "category_id"
t.string "image"
t.string "avatar"
end
add_index "personals", ["user_id"], name: "index_personals_on_user_id", unique: true, using: :btree
create_table "ranks", force: true do |t|
t.integer "user_id"
t.integer "rank"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "ranks", ["user_id"], name: "index_ranks_on_user_id", unique: true, using: :btree
create_table "registers", force: true do |t|
t.boolean "active"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "simple_captcha_data", force: true do |t|
t.string "key", limit: 40
t.string "value", limit: 6
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "simple_captcha_data", ["key"], name: "idx_key", using: :btree
create_table "streams", force: true do |t|
t.string "stream"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "seats"
t.integer "subject_stream_id"
end
add_index "streams", ["subject_stream_id"], name: "index_streams_on_subject_stream_id", using: :btree
create_table "subject_streams", force: true do |t|
t.string "subject_stream"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true 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"
t.datetime "updated_at"
t.integer "level", default: 1
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
In Ruby on Rails, the code has_many :books and belongs_to :writer is like defining relationships in the code level. It doesnt achieve anything in the database level. For example, if we write belongs_to :writer in the Book model, it just means that if there is a column writer_id in the books table, we can code something like this:
b = Book.first
b_writer = b.writer
#### equivalent to
# b_writer = Writer.find(b.writer_id)
# b_writer = Writer.where(:id => b.writer_id).first
# or b_writer = Writer.find_by_sql("SELECT writers.* from writers where writers.id = #{b.writer_id}")
It assumes that the foreign key is writer_id in books table by convention. If we need to change the foreign key for the queries generated by association, we need to specify it separately:
belongs_to :writer, :foreign_key => 'writerID'
So, in general declaring associations in models, gives us some utility methods to query those associations from database, instead of creating the queries manually. So, all the database related changes needs to be done in the migrations, like adding the column writer_id, adding index for column writer_id, setting writer_id with forieign key constraint etc. Rails does not support foreign_key constraint in migrations by default, as different databases handle foreign_key differently. For PostGre and MySQL database, you can use foreigner gem for adding foreign_key constraint.
Please read more about Rails associations