Battling to display nested data in Rails - ruby-on-rails

So I have a form with nested data that is correctly displaying in the form and is being correctly saved. However, I'm now working on trying to display this data and I'm really battling.
So I have a lot of data, but will focus on two specific types of data:
I have users, and users can create projects. The two data fields I'm battling with related to projects are:
Each project has a budget (stored as a budget_id on the project table, and for which I want to call the name of the budget)
Each project a bunch of features through a features_projects join table
Project Model
class Project < ApplicationRecord
belongs_to :user
has_one :budget
has_and_belongs_to_many :features
end
Budget Model
class Budget < ApplicationRecord
belongs_to :project
end
Features Model
class Feature < ApplicationRecord
has_and_belongs_to_many :projects
end
Extract of the index method from the Projects Controller
def index
#projects = Project.all
end
Project View to show the index
<div class="container dashboard">
<div class="center">
<h1> Your Projects</h1>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Description</th>
<th>Budget</th>
<th>User_id</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #projects.each do |project| %>
<tr>
<% if project.user == current_user %>
<td><%= project.description %></td>
<td><%= project.budget_id %></td>
<td><%= project.user.email if project.user %></td>
<td><%= link_to 'Show', project, class: "btn btn-info btn-sm" %></td>
<td><%= link_to 'Edit', edit_project_path(project), class: "btn btn-warning btn-sm" %></td>
<td><%= link_to 'Destroy', project, class: "btn btn-danger btn-sm", method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<br>
<div class="center">
<%= link_to 'New Project', new_project_path, class:"btn btn-lg btn-success" %>
</div>
</div>
I basically want to be able to display the budget saved for each project as well as the list of features that they chose. I have been trying a few different things from solutions online, but haven't had any luck :( I think perhaps I need to create a #budget variable perhaps under the index method, but I haven't had any luck with that either. Could anyone kindly help explain how I would do this?
Thanks so much!
UPDATE
Using project.budget.name reveals the following error:
ActiveRecord::StatementInvalid in Projects#index
PG::UndefinedColumn: ERROR: column budgets.project_id does not exist
LINE 1: SELECT "budgets".* FROM "budgets" WHERE "budgets"."project_...

When you say that:
Each project has a budget (stored as a budget_id on the project table, and for which I want to call the name of the budget)
This is not how has_one works, it will expect a project_id on the budget table.
I think you need to use belongs_to.
http://guides.rubyonrails.org/association_basics.html#the-has-one-association

project.budget.name #give name of budget
project.features do |feature|
feature.name # gives feature name
end

Related

How to result and validate associated data from multiple Table cells

Example: 2 tables
Table 1:
"Orders"
cells:
-id
-etc
-etc
Table 2:
"Sales_uploads"
cells:
-id
-order_id (same data as "id" in Orders table)
-etc
-etc
I have created =
Order.where(id: Sales_upload.pluck(:order_id))
from Googling, but haven't figured out where to go from here.
I have this def in my sales_upload model:
def order_sales_relationship
Order.where(id: Sales_upload.pluck(:order_id))
end
Then in the views I have: (a portion of views)
<% #orders.each do |order| %>
<tbody>
<tr>
<td class="center"><%= order.buyer.name %></td>
<td class="center"><%= number_to_currency(order.listing.price) %></td>
<td class="center"><%= order.created_at.strftime("%B %-d, %Y") %></td>
<td class="center">
<div class="field">
<% if #order_sales_relationship = true %>
<%= link_to '/sales' %>
<% else %>
<%= link_to "Upload", new_order_sales_upload_path( order, #order ), class: "btn btn-primary" %>
<% end %>
When i use this, '/sales' appears in the upload section of the table even if nothing has been uploaded. I believe the model is incorrect and may jst be validating if the cells exist, but not validating if they also match. How would i validate the matching as wlel (if this is even true)
The goal is to display an upload link ONLY if the upload hasn't happened yet. If it has, I want only an update/edit link (which is '/sales' atm as a placer, that's a whole other issue).
ok from what I'm understanding, please correct me
change
def order_sales_relationship
Order.where(id: Sales_upload.pluck(:order_id))
end
to
def order_sales_relationship
#order_sales = Order.where(id: Sales_upload.pluck(:order_id))
end
in view make this changes
<% if #order_sales.present? %>
and
<%= link_to "Upload", new_order_sales_upload_path(order, #order), class: "btn btn-primary" %>
??? where is #order

Create a child resource through a parent resource's index table - Ruby on Rails

Hi I want to put a link in a index table of a resource to create a child resource.
I got a Sale, and an operation:
class Sale < ApplicationRecord
belongs_to :user
has_one :operation, dependent: :destroy
end
class Operation < ApplicationRecord
belongs_to :sale
end
And I want to be able to create an operation through an index table of sales.
Thing is, I need it to be created on the button/link click, and not be transferred to a new operation view. (Operation has only sale_id and id as attributes)
Something like that
<table>
<tr>
<th>Sale Id</th>
</tr>
<% #sales.each do |sale| %>
<td><%= sale.id %></td>
<td><%= link_to 'Show', sale_path(sale) %></td>
<td><%= link_to 'Edit', edit_sale_path(sale) %></td>
<td><%= link_to 'Delete', sale,
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<td> <%= form_for (#operation) do |o| %>
<%= o.submit 'Create Operation'%>
<% end %>
</td>
</tr>
<% end %>
</table>
But I got this error: 'First argument in form cannot contain nil or be empty'
I also tried this:
<td>
<%= fields_for :operation, #sales.operation do |o| %>
<%= o.submit "Create Operation" %>
<% end %>
</td>
And I got this:
undefined method `operation' for Sale::ActiveRecord_Relation:0xb1a4ece4>
tried this as well :
<td>
<%= link_to 'Create Operation', 'operations#create' %>
</td>
But it sends me to the operation index view without creating an operation.
First argument in form cannot contain nil or be empty
The error means #operation is nil in the form. You should define #operation in the sales#index method as the form is in sales/index.html.erb
def index
#operation = Operation.new
end
I need it to be created on the button/link click, and not be
transferred to a new operation view
If you meant,you shouldn't be redirected to another view after the button, then you have to use AJAX. I recommend you see these Guides to understand how to do with AJAX

Generate attendance view/form in rails for all students

I am new to Rails and I am struggling on something which sounds easy but can not get it to work. I have two models Students and Attendances.
Student model:
name lastname classroom_id
Attendance model:
present:boolean absent:boolean halfday:boolean attnd_date:date student_id
Students has_many :attendances and attendance belongs_to :student.
I can make an entry for individual student and take their attendance however I want to generate a view where I show all the students (or show all students for a given classroom) and next to each student name I would like to show the three checkboxes so that I can mark who is present and absent in one go rather than one by one and submit the form.
Any help here is much appreciated. Using Rails 4 and ruby 2.2.0
Thanks
You can make an edit action, where you will find the classroom for which you want to mark attendances.
class AttendancesController < ApplicationController
def edit
#classroom = Classroom.find(<classroom-id>)
end
def update
end
end
In your view edit.html.erb
<%= form_for(#classroom, url: '/attendances/:id', method: :put) do |f| %>
<table>
<%- #classroom.students.each do |student| %>
<tr>
<td><%= student.name %></td>
<td><%= checkbox_tag "attendances[#{student.id}][present]" %></td>
<td><%= checkbox_tag "attendances[#{student.id}][absent]" %></td>
<td><%= checkbox_tag "attendances[#{student.id}][halfday]" %></td>
</tr>
<% end %>
</table>
<%= f.submit %>
<% end %>
This way, when you submit the form, you will receive these params in your update action:
`{ attendances: { '1' => { present: false, absent: true, halfday: false }, '2' => { present: true, absent: false, halfday: false }, ... } }`.
Then you can write logic in your action to save these details to database.
Note: This is kind of pseudo code. Please check the syntax and options for different html tags.
Thanks to #Jagdeep Singh for getting me up and running. I have now made the process more simple so I can get my head around. I just want to get the list of all students and create their attendances.
My view:
<% #students = Student.all %>
<%= form_for(:attendances, url: '/admin/attendances/') do |f| %>
<table>
<%= #today %>
<th>Name</th><th>Present</th><th>Absent</th><th>halfday</th>
<%- #students.each do |student| %>
<tr>
<td><%= student.first_name %></td>
<td><%= check_box_tag "attendances[#{student.id}][present]" %></td>
<td><%= check_box_tag "attendances[#{student.id}][absent]" %></td>
<td><%= check_box_tag "attendances[#{student.id}][halfday]" %></td>
</tr>
<% end %>
</table>
<%= f.submit %>
<% end %>
when I click on create attendance button it just creates just one with record with all default params and.
I am sorry I am still learning but once I get my head around on how I can create attendances for all 10 students i have in one go.

How Do I Get an Modified Column from a Rails Scaffold to Hold Information as the others?

I generated a scaffold for a To-Do List app, and I left out some columns to add later.
I ran the command to create a migration to add a new column named client and I changed my files so that it shows on the projects index and form, but when i enter something into the client field and submit, it doesn't save the information and remains blank..
Update 1:
Here is whats in my routes:
'
Rails.application.routes.draw do
root :to => 'projects#index'
resources :projects
end
'
Here is my index view:
'
<h1 id="title">Project List</h1>
<table>
<thead>
<tr id="headers">
<th>Title</th>
<th>Client</th>
<th>Description</th>
<th>Hours</th>
<th>Done</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody class="col-md-2" id="listItems">
<% #projects.each do |project| %>
<tr id="table">
<td><%= project.title %></td>
<td><%= project.client %></td>
<td><%= project.description %></td>
<td><%= project.hours %></td>
<td><%= project.done %></td>
<td><%= link_to " #{image_tag('show.png')}".html_safe, project, id:'showButton' %></td>
<td><%= link_to " #{image_tag('edit.png')}".html_safe, edit_project_path(project), id:'editButton' %></td>
<td><%= link_to " #{image_tag('destroy.png')}".html_safe, project, id:'destroyButton', method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Project', new_project_path, id:"new" %>
<footer id="footer">Copyright 2014 Kira Banks</footer>
'
To keep your application secured, Rails has a feature called Strong Parameters and the docs says:
It provides an interface for protecting attributes from end-user
assignment. This makes Action Controller parameters forbidden to be
used in Active Model mass assignment until they have been whitelisted.
So, basically you need to whitelist the new client attribute in the Projects controller by adding it to the list:
class ProjectsController < ApplicationController
# ...
# at the end of the file
private
def project_params
params.require(:project).permit(:title, :description, :hours, :done, :client)
end
end

<td> tags inside view disappearing when declaration is made on object's associated model

Been perplexed on this one for a while now. It seems like a simple oversight but I cannot get past it.
I have a basic table element to list jobs with each row representing an record in the jobs table.
<% if #jobs.any? %>
<thead>
<tr>
<th>Booking ID</th>
<th>Cleaner</th>
<th>Address</th>
<th>Status</th>
<th></th>
<th></th>
</tr>
</thead>
When I instantiate the associated model of 'address' assigned to 'addy', the row elements immediately disappear on refresh. Am I missing something here?
<% #jobs.each do |job| %>
<% job.address do |addy| %>
<tr>
<td><%= job.id %></td>
<td><%= job.jrecipient_id %></td>
<td><%= addy.label %></td>
<td>No status yet</td>
<td><%= link_to "Change Appointment", '#' %></td>
<td><%= link_to "Cancel Cleaning", job, method: :delete, data: { confirm: "You sure?" } %> </td>
</tr>
<%#distance_of_time_in_words(job.created_at, Time.now)%>
<% end %>
<% end %>
EDIT: Some more information
class Address < ActiveRecord::Base
belongs_to :job
end
class Job < ActiveRecord::Base
has_one :address
end
Since you have ''undefined methodlabel' for nil:NilClass'` ' , it means the job you want to display doesn't have an address ( address attribute of Job is Nil). Do you require an address in your validations ?
Otherwise , try to create a job with an address in the console (rails console) and display it after see what you get.
Show us your Job model maybe...
For the case when job has many addresses
<% job.address.each do |addy| %>
or for the case when job has one address
<% addy = job.address %>

Resources