I am working on something that should be simple, but I am having trouble because I am new to rails.
I have a table called TimeSheet and table called Entry.
I am working in my time_sheet show view and want to iterate through the related entries on my time_sheet.
MY models are setup like this. A user has_many :time_sheet. A time sheet belongs_to :user and has_many :entries. And entries belong_to: time_sheet
My time sheet view looks like:
<% #current.each do |t| %>
<td><%= t.entries :customer_name %></td>
<td><%= t.entries :order_number %></td>
<td><%= t.entries :time_in %></td>
<td><%= t.entries :time_out %></td>
<% end %>
My controller for the time_sheet show is:
def show
if current_user
#current = current_user.time_sheets.entries
else
redirect_to new_user_session_path, notice: 'You are not logged in.'
end
I am getting strange output that looks like this for each iteration:
#<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Entry:0xb59dfcc8>
Any help will be greatly appreciated.
Because you already
#current = current_user.time_sheets.entries
and
<% #current.each do |t| %>
So the "t" is each entry of your related time_sheets. Are you sure there is another entries? Even assume the statement don't have syntax error.
<td><%= t.entries :customer_name %></td>
How about like this.
def show
if current_user
#time_sheets = current_user.time_sheets
else
redirect_to new_user_session_path, notice: 'You are not logged in.'
end
end
In view:
<% #time_sheets.each do |sheet| %>
<% sheet.entries.each do |t| %>
<td><%= t.customer_name %></td>
<td><%= t.order_number %></td>
<td><%= t.time_in %></td>
<td><%= t.time_out %></td>
<% end %>
<% end %>
I assume customer_name, order_name are the fields name in your entry table.
Related
i'll start how my models looks:
User -> has_one :customer, has_one :employee, has_many :appointments
Customer -> belongs_to :user
Employee -> belongs_to :user
Appointment -> belongs_to :user
And now in view:
<% #appointments.order(:appointment_date).each do |appointment| %>
<% if appointment.confirmation == wait_or_confirmed?(#status) %>
<tr>
<td><%= appointment.purpose %></td>
<td><%= appointment.appointment_date %></td>
<td><%= appointment.appointment_time %></td>
<td><%= Employee.find(appointment.employee_id).first_name %> <%= Employee.find(appointment.employee_id).last_name %></td>
<td><%= Customer.find(appointment.customer_id).first_name %> <%= Customer.find(appointment.customer_id).last_name %></td>
<td><%= link_to 'Show', appointment_path(appointment), class: "btn btn-primary" %></td>
</tr>
<% end %>
<% end %>
My brother told me i shouldnt pick up informtaions from database in views so i tried using includes:
#appointments = Appointment.all
#users = User.includes(:appointments)
And after combination in view it still doesn't work. Can someone help me?
Instead of this:
Employee.find(appointment.employee_id).first_name
Do this:
appointment.employee.first_name
For performance, in the controller, you can also replace this:
#appointments = Appointment.all
With this:
#appointments = Appointment.all.includes(:employee, :customer)
By doing so, you are eager-loading all associated employee and customer data from the database in a single query, rather than one at a time.
I'm trying to develop a simple exercise log app, and I'm stuck (again). A user selects a category, and a specific workout, and I return a list of exercises belonging to that workout.
An effort is a user specific instance of an exercise.
class Exercise < ActiveRecord::Base
has_many :efforts
end
class Effort < ActiveRecord::Base
belongs_to :exercise
end
I'm retrieving the list of exercises in the efforts controller
class EffortsController < ApplicationController
def log_workout
#exercises = Exercise.where("category_id = ? AND workout_id = ?", params[:exercise][:category_id], params[:exercise][:workout_id])
#effort = Effort.new
end
end
The user logs their workout by using the following form
<%= form_tag save_workout_path, method: :put do %>
<table>
<tr>
<th>Exercise</th>
<th>Sets</th>
<th>Reps</th>
</tr>
<% #exercises.each do |exercise| %>
<%= fields_for "efforts[]", #effort do |f| %>
<tr>
<td><%= exercise.name %></td>
<td><%= f.number_field :sets %></td>
<td><%= f.number_field :reps %></td>
<%= f.hidden_field :exercise_id, :value => exercise.id %>
</tr>
<% end %>
<% end %>
</table>
<%= submit_tag "Log it" %>
<% end %>
class EffortsController < ApplicationController
def create
params[:efforts].each do |values|
if current_user.efforts.create(values)
flash[:notice] = 'Efforts were successfully saved.'
else
render action: 'new'
end
end
end
end
How right this is, I'm not sure, but it works. My problem now is trying to retrieve saved 'efforts' and allowing them to be modified through the same form. (Letting the user edit their workout log). Would appreciate any guidance/help
I have 2 classes: Posts and Comments, where posts has_many :comments and comments belongs_to post.
Each of my posts has a show page with a list of comments and I would like to paginate the comments. With the current code I have, I'm showing a list of all the comments on all the pages. So, If i have 10 comments and I want to have 2 on each page, I get 5 pages with the original 10 comments on it. Could someone shed some light?
My Code:
Posts controller:
def show
#post = Post.find(params[:id])
#comments = #post.comments.page(params[:page]).per(3)
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
"Show" views:
<%= paginate #comments %>
<% #post.comments.each_with_index do |comments, index| %>
<tr>
<td><%= index+1 %></td>
<td><%= comment.date %></td>
<td><%= comment.text %></td>
</tr>
<% end %>
</table>
You need to use the paginated object in the view, not get them fresh from the database:
<% #comments.each_with_index do |comments, index| %>
<tr>
<td><%= index+1 %></td>
<td><%= comment.date %></td>
<td><%= comment.text %></td>
</tr>
<% end %>
This gets them fresh, unpaginated:
#post.comments
I have this in the index view:
<% #submissions.each do |submission| %>
<tr>
<td><%= submission.id %></td>
<td><%= User.find_by_id(submission.user_id).name.to_s %></td>
</tr>
<% end %>
I know I am not supposed to use find_by in the view.
How can I move this to the controller (or model)?
I tried to insert this in the index method of my submission controller and using the username variable but it doesn't work.
def index
#submissions = Submission.all
#submissions.each do |submission|
username = User.find_by_id(submission.user_id).name.to_s
end
end
Model, add relation to user
class Submission
belongs_to :user
end
Controller, eager load users to avoid N+1 queries.
def index
#submissions = Submission.includes(:user).all
end
View, just project the user from each submission
<% #submissions.each do |submission| %>
<tr>
<td><%= submission.id %></td>
<td><%= submission.user.name.to_s %></td>
</tr>
<% end %>
#in controller
def index
#submissions = Submission.all
end
#in view
<% #submissions.each do |submission| %>
<tr>
<td><%= submission.id %></td>
<td><%= submission.user.name %></td>
</tr>
<% end %>
This code implies you have declared the following relations:
Submission belongs_to :user
User has_many :submissions (or has_one)
You can use eager loading (uses less queries to the DB) to improve the previous code:
#submissions = Submission.includes(:user).all
You can use an ActiveRecord association:
class Submission
belongs_to :user
# etc
end
Then in your view:
<td><%= submission.id %></td>
<td><%= submission.user.first_name</td> <!-- or whatever -->
I have several models in nested attributes that I'm working with.
I have "teams" (has many constests), and "contests" (belongs to Team). But I also want contests to reference "categories" as a child object (a contest can only have one category, and a category can have may contests).
The way the logic works is that a team is created first, then a contest, and after that I want to be able to select from a list of categories (in a partial) and establish the association (set the category_id in contest to the id value in a category). It makes sense to me how this is done when creating a new contest as a child of team, but I am hitting my head agains the wall when it comes to creating the second relationship (existing contest to an existing parent category).
The controller that gives me the show view for a contest is:
def show
#team = Team.find(params[:team_id])
#contest = Contest.find(params[:id])
#categories = Category.all
respond_to do |format|
format.html # show.html.erb
format.json { render json: [#contest] }
end
end
In the show view I have this code:
<p><b>Name:</b><%= #contest.name %></p>
<%= link_to 'Edit', edit_team_contest_path(#team, #contest) %> |
<%= link_to 'Back', team_contests_path %>
<br />
<%= render 'categories/index'%>
And my partial _index for categories contains this code:
<table>
<% #categories.each do |category| %>
<tr>
<td><%= category.level1 %></td>
<td><%= category.level2 %></td>
<td><%= category.level3 %></td>
<td><%= category.level4 %></td>
<td><%= link_to 'Show', category %></td>
<td><%= link_to 'Edit', edit_category_path(category) %></td>
<td><%= link_to 'Destroy', category, confirm: 'Are you sure?', method: :delete %></td>
<%end%>
</table>
Where I am so flummoxed is where to place the code (in the Contest or Category controller?) for setting the category-contest parent-child relationship, as well as which view (the Contest show view, or the Category _index partial?). I am pretty certain that I am not understanding something fundamental about Rails here, so if anyone could point me to the docs that might clear up my befuddlement I'd very much appreciate it.
Okay, here's how I ended up solving my problem (in case anyone finds it later and uses the same search terms I tried):
Models:
team.rb
has_many :contests, :dependent => :destroy
category.rb
has_many :contests
contest.rb
belongs_to :team, :foreign_key => "team_id"
belongs_to :category, :class_name => 'Category', :foreign_key =>"category_id"
accepts_nested_attributes_for :category
Controller:
contests_controller
def update
#contest = Contest.find(params[:id])
#team = #contest.team
if !params[:category_id].nil?
#category = Category.find(params[:category_id])
#contest.update_attributes(:category_id => #category.id)
end
respond_to do |format|
if #contest.update_attributes(params[:contest])
blah
else
blah
end
end
end
Categories View (_index), a partial in the contests/show view, includes these three bits of code:
<table>
<% #categories.each do |category| %>
<tr>
<td><%= form_for [category, #contest] do |f| %>
<% f.submit "Select" %>
<% end %></td>
</tr>
<%end%>
</table>
And that is what it takes to associate a record that belong to another parent with another parent in a different model (after the first relationship has been created).