Tables with several children - ruby-on-rails

So I have some tables: TvShow, Episodes, and Games.
TvShow - has_many Episodes, has_many Games
Episodes - belongs_to TvShow, has_many Games
Games - belongs_to TvShow, belongs_to Episodes.
The Games table has fields for tv_show_id and episode_id. Episode ID can be blank, as some games are associated with the show and not a specific episode. I have no problem listing each TV shows episode, and any games associated with that episode.
<% #tvshows.each do |tv| %>
<div class="gamebox">
<h3><%= tv.title -%></h3>
<% tv.episodes.each do |episode| -%>
<%= episode.title %><br />
<ul>
<% episode.tv_show_games.each do |g| %>
<li><%= g.title %> (<%= g.user.name %>)</li>
<% end %>
</ul>
<% end -%>
</div>
<% end -%>
However, I'd also like to be able to grab only those Games that have no episode association. What is the best way to go about doing this? I realize I'd likely have to create a method that only queries Games with empty episode_id fields, but other than that, I'm somewhat stuck. Any help is greatly appreciated!

You can use a SQL where clause
#games = Game.where('episode_id IS NULL')
or a Rails 2 selector
#games = Game.where(:episode_id => nil)
or a Rails 3 selector
#games = Game.where(episode_id: nil)

Could you please try this?
rails 3
#game = Game.where(:episode_id => nil)
rails 2
#game= Game.find_all_by_episode_id(nil)

Related

How to loop through a self referential model in Ruby on Rails

I'm new to ruby on rails and I'm building a wiki app where the navigation is to be sorted by categories. Each article, or page, can belong to a category, but a category can also be a sub-category of another category. An administrator will be able to create new categories or sub-categories calling for a dynamic approach to generating a list of categories for the menu. I'm trying to figure out how to display a list of all parent categories and all of their children and grandchildren categories where the menu would look something like this:
1. Parent1
1.a Child1
1.b Child2
2. Parent2
2.a Child1
2.a.1 Grandchild1
I currently have some nested loops in my view which kind of work, but it's not dynamic since it will only show the first two generations, and I would have to repeat the code to show more.
Model:
class Category < ApplicationRecord
has_many :sub_categories, class_name: "Category", foreign_key: "category_id"
belongs_to :category, class_name: "Category", optional: true
end
Controller:
class CategoriesController < ApplicationController
def index
#sorted_categories = Category.order(:sort_number).where("category_id IS NULL")
#sub_categories = Category.order(:sort_number).where("category_id IS NOT NULL")
end
end
View:
<% if #categories.nil? %>
<h3>There are currently no categories.</h3>
<% else %>
<ul>
<% #sorted_categories.each do |c| %>
<li><%= c.name %><%= link_to 'Move Up', categories_move_up_path(c) %> Sort:<%= c.sort_number %></li>
<% #sub_categories.each do |s| %>
<% if s.category_id == c.id %>
<ul>
<li>
<%= s.name %><%= link_to 'Move Up', categories_move_up_path(s) %> Sort:<%= s.sort_number %>
</li>
</ul>
<% end %>
<% end %>
<% end %>
</ul>
<% end %>
Any advice would be greatly appreciated, thanks!
Have a look at the acts_as_list gem, it does exactly what you want.
It will define a parent_id column, and each object will be a child of a parent, so that you can create infinite tree of categories ans sub-categories.
It also provides the methods to move objects up and down.

Rails 4 - How to populate an array through a form

I have three tables: illness, symptom and a secondary table to link the other two on a has_many through: relationship.
I wish to implement a system where users type in their symptoms and receive a list of possible illnesses.
Using the code below I can use find(1,2), for example, to show all illnesses that have symptoms 1 and 2 simultaneously. However, I want these two constants to be user-supplied data fed through a form. I'm somewhat new to RoR so I don't know how to do this.
symptoms = Symptom.find(params[:symptom_ids]) # symptom_ids is an array of ids
illnesses = Illness.joins(illness_symptoms: :symptom)
.where("symptoms.id in (?)", symptoms)
.group("illnesses.id")
.having("count(illnesses.id) >= ?", symptoms.length)
In the model:
scope :with_symptoms, -> (symptoms) { joins(illness_symptoms: :symptom)
.where("symptoms.id in (?)", symptoms)
.group("illnesses.id")
.having("count(illnesses.id) >= ?", symptoms.length) }
I use these with Illness.with_symptoms(Symptom.find(1,2)) (I'm looking for a way to replace 1,2 with user-supplied data).
You can do something like this in a form:
<% form_tag some_path do %>
<% #symptoms.each do |symptom| %>
<%= label_tag do %>
<%= check_box_tag "symptom_ids[]", symptom.id %>
<%= symptom.name %>
<% end %>
<% end %>
<% end %>
User will be able to use checkboxes to choose symptoms.

RoR View: List results grouped under categories

I am trying to group a set of products (obtained typing a query) based on taxonomy(on of the attributes of a product)
My desired output is
Taxonomy 1
prod1 prod2 prod3 prod4
prod 5 ...
Taxonomy 2
pod6 prod7
Taxonomy 3
prod8 prod9..
I am using the following code in the view:
<% taxonomies.each do |taxonomy|%> #"taxomonies" is a set of unique taxonomies for retrieved products
<h1><%= taxonomy%></h1>
<ul>
<% collection.each_with_index do |product,i| %> #"collection" is the list of products retrieved
<li>
<%#ptaxon = product.get_taxonomy%>
<%if #ptaxon == taxonomy%>
<%code for listing product%>
<%end%>
</li>
<%end%>
</ul>
<%end%>
This groups the products based on taxonomies but the format is not what I desire. Could someone please point out my mistake.
EDIT: also tried using < br > , but doesn't help!
This is the output I'm getting. I want the taxonomies earrings, bracelets and necklaces to start from a new line.
Thanks
If you have your associations setup correctly, you can do it like this:
<% taxonomies.each do |taxonomy| %>
<%= taxonomy.name %>
<% taxonomy.products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
Models should be something like:
class Taxonomy
has_many :products
end
class Product
belongs_to :taxonomy
end

Rails: App displays table/model name instead of data from table

I'm very new to rails and putting together my first app. Please bear with me!
I'm making an app that lets the user rate the video games they are playing. On the site I've made a page where the user can see a list of all the games that he/she has rated in the past.
I'm running into some issues and I think it's pretty simple but it's driving me crazy.
In the controller I have:
def index
#rate = Rate.where(:rater_id => current_user.id)
#ratename = Game.where(:id => #rate.first.rateable_id)
end
And in my view I have:
<% #rates.order("created_at desc").each do |rates| %>
You are playing <%= #ratename.name %></div>
<% end %>
Where I'm confused is that in the browser this is displayed: "You are playing Game"
How do I get it to display the name of the game not just "Game"?
UPATE:
Model for rate:
class Rate < ActiveRecord::Base
attr_accessible :rateable_id, :rater_id
belongs_to :user
belongs_to :game
end
#ratename = Game.where(:id => #rate.first.rateable_id)
means that you find Game with all attributes, not only name.
The right way:
in controller:
#rates = current_user.rates.order("created_at desc") #will work if you made correct associations (user has many rates)
in view:
<% #rates each do |rate| %>
You are playing <%= rate.game.name %></div>
<% end %>
rate.game.name will work if you made correct associations: game has many rates, rate belongs to game.
Try referring to the associations directly.
Controller:
def index
#rates = current_user.rates.order("created_at desc")
end
View:
<% #rates.each do |rate| %>
You are playing <%= rate.game.name %>
<% end %>
my suggestion just do this
in index
def index
#rates = current_user.rates.includes(:game).order("created_at desc")
end
in view
<% #rates.each do |rate| %>
You are playing <%= rate.game.name %></div>
<% end %>
this will solve your problem plus it will improve your server efficiency

Rails views based on HABTM Category

So I have this app where I'm using a HABTM association to determine "User Skills"; When a new user is created (via the new user view) the user can declare his/her skills via a group of HABTM Checkboxes available on that view with the form...
What I want to do is to have a view where I have Links based on the different skills, for example: "policemen", "doctors", "musicians" etc. And these links should point to other views where I can show to the visitor a list of only the users that belong to the specific category they clicked on.
My users/skills models (association part) look like this:
#User Model
class User < ActiveRecord::Base
has_and_belongs_to_many :skills
#Skill Model
class Skill < ActiveRecord::Base
has_and_belongs_to_many :users
And (if it's helpful) my HABTM checkboxes look like this:
<p> What Skills do you have?
<% for skill in Skill.find(:all) %>
<div>
<%= check_box_tag "user[skill_ids][]", skill.id, #user.skills.include?(skill) %>
<%= skill.name %>
</div>
<% end %>
</p>
Let's say the skills we have are: "policeman, doctor, musician" for example... How can I create links in a view wich point to the group of users that have X skill and then with what code could I render some views that display lists with only the users that belong to X skill category?
I bet the solution is really simple... But I'm missing something obvious, maybe. Could you point me in the right direction?
Thanks!
In config/routes.rb:
resources :skills
Generate a SkillsController with rails g controller skills and put there:
def index
#skills = Skill.all
end
def show
#skill = Skill.find(params[:id])
end
Then your views:
#app/views/skills/index.html.erb
<ul>
<% #skills.each do |skill| %>
<li><%= link_to skill.name, skill_path(skill) %></li>
<% end %>
</ul>
and
#app/views/skills/show.html.erb
<h1>Users who have the <%= #skill.name %> skill</h1>
<ul>
<% #skill.users.each do |user| %>
<li><%= user.full_name %></li>
<% end %>
</ul>
First of all dont use the has_and_belongs_to_many. Here is a link to RoR Guides showing how you are supposed to do the has_many :through assosiation. http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
Secondly if you want to show your user that have 'x' skill it just the skills#show action.
def show
#skill = Skill.find params[:id]
#users = #skill.users
end
And on your links to view this would be something like skill_path(skill)

Resources