Rails: category and subcategory tree - ruby-on-rails-3

Hi I am new to rails ... I am trying to make a category and subcategory tree in rails...can you please guide me..
my schema is as follows:
create_table "categories", :force => true do |t|
t.string "name", :null => false
t.string "aka", :null => false
t.integer "parent"
end

you can find information here :
http://railscasts.com/episodes/162-tree-based-navigation

Related

Rails: Trouble With Model Association Using Ancestry Gem (Tree Structur Model)

I am working on a simple app that allows a user to write a post (parent_post), and another user to answer this post (child_post).
I am using the Ancestry gem to track the relationships between the posts.
Ancestry is a gem/plugin that allows the records of a model to be organised as a tree structure (or hierarchy). It exposes all the standard tree structure relations (parent, root, children, ancestors...).
The database schema.rb of the app:
create_table "posts", :force => true do |t|
t.text "title"
t.text "content"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
t.string "ancestry"
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 "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "name"
end
The challenge:
I want to display informations about the author of the parent_post in the show view of a child_post .
Via the Ancestry gem you can call for "parent" and address all the columns inside of the posts table.
The posts table (see above) has a user_id column, so I can call
#post.parent.user_id
to show me the User ID, which works.
But I would like to show the username instead of the user_id.
Of course, user_id and username (name) are via the users table connected (see schema.rb above), but how can I address them here?
#post.parent.user_id.name is not working.
The models:
class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
has_ancestry
belongs_to :user
end
I am still quite new to Rails and stuck here. Is there maybe a super easy solution I am not seeing?
Thank you so much for helping out!
How about #post.parent.user.name? I recommend making this a method on the Post model rather than your view or controller. Call it #post.original_poster_name or similar.

has_many through relationship - how to call the join table to print out multiple subcategory's contents?

Goal is to print out the content within each subcategory/subcategories.
I have a list of categories and then subcategories. The subcategories and contents have a has_many :through relationship. I need to be able to click on one or more subcategories and then show the related contents. Not sure of a couple things:
1) Do I make a subcategories controller and build out the filtering there or go through the contents controller?
2) Should I just make a custom route?
Here is what I have now.
contents table
create_table "contents", :force => true do |t|
t.string "title"
t.text "short_description"
t.text "long_description"
t.datetime "published_date"
t.datetime "edited_date"
t.string "read_length_time"
t.string "tag"
t.integer "author_id"
t.integer "contenttype_id"
t.string "collection"
t.integer "collection_id"
t.string "subcategory"
t.integer "subcategory_id"
t.boolean "published"
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 "infographic_file_name"
t.string "infographic_content_type"
t.integer "infographic_file_size"
t.datetime "infographic_updated_at"
t.string "video"
end
subcategories table
create_table "subcategories", :force => true do |t|
t.string "title"
t.integer "category_id"
t.string "content"
t.integer "content_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
join table
create_table "subcats_contents", :id => false, :force => true do |t|
t.integer "subcategory_id"
t.integer "content_id"
end
add_index "subcats_contents", ["content_id"], :name => "index_subcats_contents_on_content_id"
add_index "subcats_contents", ["subcategory_id", "content_id"], :name => "index_subcats_contents_on_subcategory_id_and_content_id"
add_index "subcats_contents", ["subcategory_id"], :name => "index_subcats_contents_on_subcategory_id"
routes.rb
match 'contents/filter_association/:id' => 'contents#filter_association', :as => 'filter_association', :via => :get
contents controller
def filter_association
#subcategory = Subcategory.find_by_id(params[:id])
Subcategory.where.merge(-> { joins(:content_id) })
respond_to do |format|
format.html
format.json { render json: #content }
end
end
Here is the view for click on the subcategories :
<table>
<% #subcategories.each do |subcategory| %>
<tr>
<td><%= subcategory.title %></td><br/>
<td><%= check_box_tag (:subcategory) %></td>
</tr>
<% end %>
<%= submit_tag "submit" %>
<table>
ERROR: wrong number of arguments (0 for 1)
You got an error because you didn't pass any params to where method.
If I understood correctly, you are receiving some list of subcategories from the user form and you want to get the list of all contents associated with those subcategories.
Content.joins(:subcategories).where(:subcategories => {:id => <variable with subcategory ids>}).group(:content => :id)

rails no such column error

I have the following app. A Movie has many reviews, a moviegoer has many reviews.
When I try to associate a review with a movie I get the following error
Review Load (0.1ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
after using a sql gui editor I found that the correct query should be
SELECT "reviews".* FROM "reviews" WHERE "movie_id" = 5
review.rb
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :moviegoer
attr_protected :moviegoer_id
end
movie.rb and moviegoer.rb have
has_many :reviews
in them.
schema.rb
ActiveRecord::Schema.define(:version => 20130222225620) do
create_table "moviegoers", :force => true do |t|
t.string "name"
t.string "provider"
t.string "uid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "movies", :force => true do |t|
t.string "title"
t.string "rating"
t.text "description"
t.datetime "release_date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "reviews", :force => true do |t|
t.integer "potatoes"
t.text "comments"
t.integer "moviegoers_id"
t.integer "movies_id"
end
end
What am I doing wrong? why is rails querying "reviews"."movie_id" instead of just "movie_id"?
You have the wrong column name in your migration. The rails convention is that foreign keys are to be singular. If they are not then you need to tell rails what the foreign key is with an options hash on the association.
Either rollback your migration, fix the column name (moviegoers_id is wrong as well) then migrate again, or tell rails the foreign key.
Class Review < ActiveRecord::Base
belongs_to :movie, :foreign_key => 'movies_id'
belongs_to :moviegoer, :foreign_key => 'moviegoers_id'
end
And the same has to happen on the has many side of both models.

ActsAsTaggableOn after own tag implementation

I had my own implementation of tags in my rails application and wanted to replace it by the ActsAsTaggableOn gem. I generated the migration and deleted all the migrations with tags in it, but forgot to rollback first, so I just did rake db:reset. Now the schema looks fine with tag and taggable in it, but if I try Tags out in the Console, by just typing Tag i get
NameError: uninitialized constant Tag
What causes this error, I thought I just did like in the Railscast.
My schema.rb looks like this:
# encoding: UTF-8
# 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 => 20121009203921) do
create_table "comments", :force => true do |t|
t.text "content"
t.integer "user_id"
t.integer "message_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "events", :force => true do |t|
t.string "name"
t.datetime "start_at"
t.datetime "end_at"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "messages", :force => true do |t|
t.text "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "taggings", :force => true do |t|
t.integer "tag_id"
t.integer "taggable_id"
t.string "taggable_type"
t.integer "tagger_id"
t.string "tagger_type"
t.string "context", :limit => 128
t.datetime "created_at"
end
add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
create_table "tags", :force => true do |t|
t.string "name"
end
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "encrypted_password"
t.string "salt"
t.boolean "admin", :default => false
t.string "phone"
t.string "street"
t.string "zip"
t.string "location"
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
end
Thanks for your help!
I had to have a model, to get it work in the console.

rails add_column with default value but the default value don't take effect

My rails version is 3.2.8 and use the default database.
This is my migration code:
class AddQuantityToLineItem < ActiveRecord::Migration
def change
add_column :line_items, :quantity, :integer,:default=>1
end
end
I find a explaination about :default option here and as it said,when i create a
new LineItem ,it should have a default quantity=1,but here is what i get from rails console:
lineb=LineItem.new
#<LineItem id: nil, product_id: nil, cart_id: nil, created_at: nil, updated_at: nil, quantity: nil>
And when i get LineItem from the database,the quantity field is nil
too.
And here is the db/schema.rb :
ActiveRecord::Schema.define(:version => 20121008065102) do
create_table "carts", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "line_items", :force => true do |t|
t.integer "product_id"
t.integer "cart_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "quantity"
end
create_table "products", :force => true do |t|
t.string "title"
t.text "description"
t.string "image_url"
t.decimal "price", :precision => 8, :scale => 2
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
Your migration should work fine. Based on your schema though it looks like it hasn't actually taken effect, since t.integer "quantity" has no default value.
The line in the schema for quantity should look like this:
t.integer "quantity", :default => 1
Make sure you have actually run your migration (bundle exec rake db:migrate), and if that doesn't work then rollback (bundle exec rake db:rollback) and run the migration again (as #surase.prasad suggested).