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
Related
I use Devise gem for authentication.
In database I have users table and posts table in my database schema (and Post controller).
In post controller I want to find all posts assigned to specific user. I have user_id in posts table.
How to get all user's posts or how to check if specific post is assigned for SIGNED IN user.
I thought about something like this (of course is only pseudocode:
current_user.id == Post.where(params:[post_id]).user_id
So how to get current user id in Devise and how to check the current user id is the same like eg. user_id assigned to viewing post (I want to add 'edit' function when current user is post owner) and how to find all post which current user is owner.
Associations
Firstly, your user_id column in your posts table is what's known as a foreign_key
Foreign keys are used in relational database systems to give you the ability to call associative data from a single record. Simply, it means that you'll be able to use the ActiveRecord associations to call the data you require, rather than having to call it individually:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :posts
end
#app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
end
This will give you the ability to use the following call:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
#posts = current_user.posts
end
end
You'll be best served looking up the has_many association:
Fix
In regards to showing your posts for your users, you need to be sure that you have the correct "flow" set up. What I mean is you need some condition to know whether your user is signed in & that #posts is set:
#app/views/posts/index.html.erb
<% if #posts.present? %>
<% #posts.each do |post| %>
<%= post.title %>
<% end %>
<% end %>
Maybe this is the first time you use Devise. You can access current_user inside controllers or views. I imagine you could do something like this
In controller (posts_controller.rb):
#posts = current_user.posts
In view (posts/show.html.erb, I guess):
if current_user.id = #post.current_user
#render something here
end
Get all post which current user is owner.
#posts = Post.where(:user_id => current_user.id)
and on your view
<%-# commented : checking if #posts is empty -%>
<% if #posts.empty? %>
<span>Sorry, post is empty </span>
<% else %>
<%= #posts.each do |p| %>
<% if p.user_id == current_user.id %>
<% link_to "edit", edit_path(p) %>
<% end %>
<% end %>
<% end %>
There are many ways you could get current_user posts. I'll go the long way.
we need
an action
an action view and a partial
a route
a link_to
* action *
def my_posts
#posts = current_user.posts.all.order(created_at: 'DESC')
end
* view *
my_posts.html.erb
<% if #posts.present? %>
<%= render 'posts' posts: #posts %>
<% else %>
<h1>You don't have any posts yet! create one</h1>
<% end %>
_posts.html.erb
<%posts.each do |post| %>
<%= post.title %>
<% end %>
index.html.erb
<%= render 'posts' posts: #posts %>
route
get 'post' => 'posts#my_posts', as: :my_posts
link_to
<%= link_to 'My posts', my_posts_path %>
I may be late but someone can find it useful :)
I have read so much about Rails in the past week in the process of trying to learn it. The problem is when I need something I find it difficult to recall where I read it! ha ha
I have two models: Guest and Booking where Guests has_many Bookings. Therefore the Booking model has a guest_id field included.
I would like to retrieve all the booking data and the guest data and display in a view as one object. I know I have seen a simple solution to this (in the Rails doc I think) that does just this.
At the moment I'm doing the following in my BookingsController:
#bookings = Booking.all
and in my associated view I have:
<% #bookings.each do |booking| %>
<p><%= booking.id %></p>
<p><%= booking.email %></p> //this does not work as email is in guests table!!!
<% end %>
but how can I get the linked Guest table included too?
If your booking belongs to guest
class Booking < ActiveRecord::Base
belongs_to :guest
...
end
you can first include guest to avoid n+1 queries
#bookings = Booking.includes(:guest).all
and then in view, traverse the association
<% #bookings.each do |booking| %>
<p><%= booking.id %></p>
<p><%= booking.guest.email %></p>
<% end %>
In your bookings controller:
#bookings = Booking.includes(:guest).all
I have a form that takes bookings for an event for people. The form displays events vertically, and a name & checkbox for each of the possible people next to each event.
How should I best convey the two pieces of information that i need per checkbox? that is, the event_id and the person_id
I'm not totally sure wether I got you right. This is the model I assume you're talking about:
# event.rb
class Event
has_many :people
scope :possible_people, -> { #whatever .. }
end
# person.rb
class Person
belongs_to :event
end
# events_controller.rb
class EventsController
def index
#events = Event.all
end
end
And this might be a possible solution to change an events relation to people:
# index.html.erb
<ul id="events">
<% #events.each do |event| %>
<li class="event">
<%= form_for #event do |form| %>
<% event.possible_people.each do |person| %>
<%= check_box_tag "event[person_ids][]", person.id, #event.people.include?(person) %>
<% end %>
<%= f.submit_tag 'Save Event' %>
<% end %>
</li>
<% end %>
</ul>
The important part is <%= check_box_tag "event[person_ids][]", person.id, #event.people.include?(person) %> where you actually change the the relation of a specific person to the event.
Good luck ;)
Well, you can try out something like below line, I am assuming you have a multiselect checkboxes and i am passing a Hash of event_id => plate_id as value to checkbox.
<%= check_box_tag 'booking[event_people_ids][]', {booking.event_id => booking.plate_id} %>
You will get the value in params as:
booking => {event_people_ids =>["{"72"=>"3"}}
I ended up doing this:
<%= check_box_tag "booking[]", "#{event.id}-#{person.id}" %>
and then in then to process them:
params[:booking].each do |booking|
booking = booking.split('-')
a = {
:booking_id => #booking.id,
:person_id => booking[1],
:event_id => booking[0]
}
Appointment.create(a)
end
I was hoping for a more railish way to do it but this works.
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)
I know that I might have too much logic in my view, so I'm wondering how I can include it in my controller:
Controller:
def purchasers
#deal = Deal.find(params[:id])
#pl = #deal.purchases
end
View:
<% title "List Of Purchases" %>
Total Purchases: <%= #pl.count %><BR><BR>
<%
#pl.each do |p|
u = User.find(p.user_id)
%>
<%= u.email %><BR>
<%
end
%>
I'd suggest that you remove the call to User.find inside the view code.
It looks like you're looking up the user from the user_id stored in the purchase. Why not in the model use:
class Purchase < ActiveRecord::Base
belongs_to :user
...
end
And then in the view code:
<% #pl.each do |purchase| %>
<%= purchase.user.email %><BR>
<% end %>
Hope this helps.
It looks like you might not have set up your associations correctly in your Purchases and Users models. Instead of doing u = User.find(p.user_id) you should be able to write p.user.email, assuming that each Purchase belongs_to :user.
if your Purchase model belongs to User model, you don't need to find User with User.find.
if not, belong your Purchase model to User model then
<% #pl.each do |p| %>
<%= p.user.email %>
<% end %>
Its also worth noting the following can be improved to make use of Rails' skills when it comoes to caching collections:
<%= #pl.count %>
to
<%= #pl.size %>
The size method will return the number of purchases but won't load the objects into memory again as they have already been looked up in the controller.