Dynamically render a partial using a tabbed nav in Rails - ruby-on-rails

I have a web app that contains a three models - Customers, Jobs and Rooms. They are associated as follows:
class Customer < ActiveRecord::Base
has_many :jobs
class Job < ActiveRecord::Base
belongs_to :customer
has_many :rooms
class Room < ActiveRecord::Base
belongs_to :job
Users can create as many rooms as they want.
Currently, I have a view that looks like this:
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title center">Room Information</h3>
</div>
<div class="panel-body">
<ul class="nav nav-tabs" role="tablist">
<% #job.rooms.each do |room| %>
<li><%= link_to room.room_type %></li>
<% end %>
</ul>
<%= render 'layouts/roomview' %>
<div class="pull-right">
<%= link_to new_job_room_path(#job, #customer), class: "btn btn-primary" do %>
<span class="glyphicon glyphicon-plus"></span> Add New Room
<% end %>
</div>
</div>
</div>
</div>
In this view, I would like to click each tab and then have the roomview partial render for the room associated to the corresponding tab.
My _roomview.html.erb partial is as follows:
<% #job.rooms.each do |job| %>
<div class="table-responsive">
<table class="table">
<tr>
<h4 class="info-text"><%= room.room_type %> Information</h4>
</tr>
<tr class="info">
<th class="col-md-2 info-text"><u>Room Details</u></th>
<th class="col-md-2"></th>
<th class="col-md-2 info-text"><u>Door Style Details</u></th>
<th class="col-md-2"></th>
<th class="col-md-2 info-text"><u>Drawer Box Details</u></th>
<th class="col-md-2"></th>
</tr>
<tr>
<td class="col-md-2"><strong>Room Type:</strong></td>
<td class="col-md-2"><%= room.room_type %></td>
<td class="col-md-2"><strong>Upper Door Style:</strong></td>
<td class="col-md-2"><%= room.upper_door_style %></td>
<td class="col-md-2"><strong>Drawer Box Style:</strong></td>
<td class="col-md-2"><%= room.drawer_box_style %></td>
</tr>
<tr>
<td class="col-md-2"><strong>Material Type:</strong></td>
<td class="col-md-2"><%= room.material %></td>
<td class="col-md-2"><strong>Lower Door Style:</strong></td>
<td class="col-md-2"><%= room.lower_door_style %></td>
<td class="col-md-2"><strong>Drawer Track Style:</strong></td>
<td class="col-md-2"><%= room.track_style %></td>
</tr>
<tr>
<td class="col-md-2"><strong>Material Details:</strong></td>
<td class="col-md-2"><%= room.material_details %></td>
<td class="col-md-2"><strong>Drawer Front Style:</strong></td>
<td class="col-md-2"><%= room.drawer_front_style %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr>
<td class="col-md-2"><strong>Exterior Colour:</strong></td>
<td class="col-md-2"><%= room.exterior_colour %></td>
<td class="col-md-2"><strong>Panel Back Style:</strong></td>
<td class="col-md-2"><%= room.panel_back_style %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr>
<td class="col-md-2"><strong>Interior Colour:</strong></td>
<td class="col-md-2"><%= room.interior_colour %></td>
<td class="col-md-2"><strong>Finished End Style:</strong></td>
<td class="col-md-2"><%= room.finished_ends %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr class="info">
<th class="col-md-2 info-text"><u>Counter Top Details</u></th>
<th class="col-md-2"></th>
<th class="col-md-2 info-text"><u>Molding Details</u></th>
<th class="col-md-2"></th>
<th class="col-md-2 info-text"><u>Custom Order Details</u></th>
<th class="col-md-2"></th>
</tr>
<tr>
<td class="col-md-2"><strong>Counter Top Material:</strong></td>
<td class="col-md-2"><%= room.counter_top_material %></td>
<td class="col-md-2"><strong>Closed To Ceiling:</strong></td>
<td class="col-md-2"><%= room.closed_to_ceiling %></td>
<td class="col-md-2"><strong>Custom Order Name:</strong></td>
<td class="col-md-2"><%= room.order_name %></td>
</tr>
<tr>
<td class="col-md-2"><strong>Counter Top Supplier:</strong></td>
<td class="col-md-2"><%= room.counter_top_supplier %></td>
<td class="col-md-2"><strong>Crown Molding:</strong></td>
<td class="col-md-2"><%= room.crown_molding %></td>
<td class="col-md-2"><strong>Custom Order Details:</strong></td>
<td class="col-md-2"><%= room.order_description %></td>
</tr>
<tr>
<td class="col-md-2"><strong>Counter Top Colour:</strong></td>
<td class="col-md-2"><%= room.counter_top_colour %></td>
<td class="col-md-2"><strong>Under Cabinet Molding:</strong></td>
<td class="col-md-2"><%= room.under_cabinet_molding %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr>
<td class="col-md-2"><strong>Counter Top Edge:</strong></td>
<td class="col-md-2"><%= room.counter_top_edge %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr>
<td class="col-md-2"><strong>Counter Top Backsplash:</strong></td>
<td class="col-md-2"><%= room.backsplash %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
<tr>
<td class="col-md-2"><strong>Sink Install:</strong></td>
<td class="col-md-2"><%= room.sink_install %></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
<td class="col-md-2"></td>
</tr>
</table>
</div>
<% end %>
Here are my routes:
resources :customers do
resources :jobs
end
resources :jobs do
resources :rooms
end
And finally, here is my jobs show controller:
def show
#job = Job.find(params[:id])
#customer = Customer.find(params[:customer_id])
end
As it stands right now, when I load the view I am getting a controller name error for the show action. The error states that I have an undefined method for 'room'.
Considering my stated functionality above - can anyone troubleshoot this? I am unsure of how to structure the show action to properly render my partial.
Here is the exact error string:
undefined local variable or method `room' for #<#<Class:0x007fa01f9827b0>:0x007fa01f9a8d48>

Several issues here:
Controller
If your models are nested, why don't you use your associations in the controller calls:
#app/controllers/jobs_controller.rb
class JobsController < ActiveRecord::Base
def show
#customer = Customer.find params[:customer_id]
#job = #customer.jobs.find params[:id]
end
end
Far more efficient!
Error
Your error is quite explicit:
undefined local variable or method `room'
This means that somewhere in your show view, your app is going to try and reference room (local var) without it being defined. Without a specific reference to the error in question, I'll have to work through to the cause of the issue:
#app/views/jobs/_roomview.html.erb
<% #job.rooms ...
Firstly, the above is incorrect. In partials, you need to pass "local" variables (as otherwise, they lose their modularity):
<%= render partial: "roomview", locals: { job: #job } %>
What would be better would be to use the following:
<%= render partial: "roomview", collection: #job.rooms, as: :room %>
#_roomview.html.erb
(no need for .each any more)
<div class="table-responsive"> ....
--
Finally, I would look at how you're calling the various dependencies of your show view. Specifically the partial, but also any links etc. You have the following link:
<%= link_to room.room_type %>
Surely you'd be better calling <%= link_to "Room", room.room_type %>

Related

Ruby on Rails: Search for database items (students)

I have 2 questions.
I want to add a search to my database. All items of my database are shown at the main page, there's a list where you can see all of the students. Can anyone tell me how I can add a function to my search? Where should I start, what should I create? And can you also tell me what any of that steps are doing? And how can I display the search results?
<p class="lead">Student management at a glance.
<form class="form-inline my-2 my-lg-0">
<!-- Search should be here -->
</form>
</div>
</div>
</div>
<!-- Student Summary -->
<div class="row justify-content-md-center">
<div class="col-12">
<div class="card">
<div class="card-header">
<i class="fas fa-graduation-cap"></i> Students
<div class="btn-group float-right">
<%= link_to new_student_path, :class => "btn btn-outline-dark btn-sm" do %>
<i class="fa fa-plus fa-fw"></i>
New
<% end %>
</div>
</div>
<table class="table table-hover">
<thead class="thead">
<tr>
<th scope="col"><div class="btn btn-fhg-0"><i class="fas fa-hashtag"></div></i></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "surname", "Name, Surname" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "room_id", "Room" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "harddrive_id", "Hard Drive" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "key_id", "Key" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "os", "OS" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "manager" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "pawn" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "eol", "EOL" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><%= sort_link "comment" %></div></th>
<th scope="col"><div class="btn btn-fhg-0"><i class="fas fa-bars"></i></div></i></th>
</tr>
</thead>
<tbody>
<% counter = 1 %>
<% #students.each do |student| %>
<tr>
<td class="align-middle"><%= counter %></td>
<td class="align-middle"><%= student.to_s %></td>
<td class="align-middle"><%= Room.find(student.room_id).to_s %></td>
<td class="align-middle"><%= student.harddrive %></td>
<td class="align-middle"><%= student.key %></td>
<td class="align-middle"><%= student.os.capitalize %></td>
<td class="align-middle"><%= student.manager %></td>
<td class="align-middle"><%= student.pawn ? 'Paid' : 'Not paid' %></td>
<td class="align-middle"><%= student.eol.strftime("%d.%m.%Y") %></td>
<td class="align-middle" data-toggle="popover" title="<%= student.to_s %>" data-content="<%= student.comment %>"><%= truncate(student.comment, length: 30, separator: ' ') %></td>
<td>
I also want to list the amount of items of a category I have saved in my database. As example:
There are 50 students, 60 hard drives, 70 keys and 80 rooms.
Is it possible to list the exact amount of items on my page? Something like
<h1>There are <%= amount of students %> total queries.</h1>
Thanks!
You should create a StudentsController and add a search method in it to search for the students.
eg. below search method will search students on the basis of name
class StudentsController < ApplicationController
def search
#students = Student.where(name: params[:name])
end
end
And in routes
resources :students do
collection do
get :search
end
end

SET ASP.NET MVC4 button value

I'm a newbie.
My problem is that i have a button and i want to set the value by a ASP.NET variable.
<input type="button" id="mybt" value="<%=Student.Name %>" />
This code is not working.
The code:
<%var Products = (IEnumerable<Demo.Models.Product>)ViewBag.Products;%></div>
<div>
<table border="1">
<tr>
<td>ID</td>
<td>Name</td>
<td>Price</td>
</tr>
<%foreach(var product in Products)
{ %>
<tr>
<td style="width:68px;height:20px">
<%=product.Id %>
</td>
<td style="width:120px">
<%=product.Name%>
</td>
<td style="width:120px">
<%=product.Price %>
</td>
<td style="width:120px">
<input type="button" value='<%=product.Id%>' />
<%} %>
</td>
</tr>
Instead of <%=Student.Name %> use this: #Student.Name
Provided that "Student" is the model name and "Name" is the property you want.
The reason for this is because <%= %> works for aspx but not the razor view engine which is probably what you have chosen for your MVC solution.

I want to show data from two tables in a single view

I have two tables: one named um_org_data and the other addresses.
The problem is that I want to show the data from um_org_data with addresses where addresses has a foreign key um_org_datum_id.
Here is the code of my view in which I want to show the data from two tables together:
<p id="notice"><%= notice %></p>
<div class="container">
<div class="row">
<div class="span3 pull-right">
<div class="well">
<h2>Heading</h2>
<p>Sample text</p>
</div>
</div>
<div class="span9">
<h2>Organization Details</h2>
<table class="table table-hover">
<tr>
<th col span="1" style="width: 200px">
</i> Organization Name:
</th>
<td><%= #um_org_datum.org_name %></td>
</tr>
<tr>
<th col span="1" style="width: 250px">
</i> Organization Description:
</th>
<td><%= #um_org_datum.org_description %></td>
</tr>
<tr>
<th col span="1" style="width: 250px">
</i> Web Domain:
</th>
<td><%= #um_org_datum.webdomain %></td>
</tr>
<tr>
<th col span="1" style="width: 200px">
<%= fields_for :address_attributes do |p| %>
<%= p.label 'Office Address' %><br />
</th>
<td><%= p.address.offc_addr %></td>
<% end %>
</tr>
<tr>
<th col span="1" style="width: 200px">
</i> Office Phone Number:
</th>
<td><%= #um_org_datum.offc_ph %></td>
</tr>
</table>
<div class="control-group">
<div class="controls">
<a class="btn" href="/um_org_data" style="text-color:black">View all</a>
</div>
</div>
</div>
</div>
</div>
I don't use any join query in the controller as I don't know how to use join query. If this problem needs a join query, please tell me what is the syntax and what I have to change in the view form to show attributes of both tables.
table name: um_org_data , attributes: id, oeg_name, org_description, webdomain
table name: adrresses , attributes: id, offc_addr, um_org_datum_id
Thanks in advance!
Do you have 1:n association? Am I right?
Definitely remove the fields_for...you are not in a form!
Change this:
<tr>
<th col span="1" style="width: 200px">
<%= fields_for :address_attributes do |p| %>
<%= p.label 'Office Address' %><br />
</th>
<td><%= p.address.offc_addr %></td>
<% end %>
</tr>
to this:
<tr>
<th col span="1" style="width: 200px">Office Address</th>
<%= #um_org_datum.addresses.each do |p| %>
<td><%= p.office_addr %></td>
<% end %>
</tr>
Check out the markup, but the logic should be clear now..
I'm assuming you have the following in your models
um_org_datum
has_many :addresses
address
belongs_to :um_org_datum
Does this work?
<tr>
<th col span="1" style="width: 200px">Office Address</th>
<%= #um_org_datum.addresses.each do |p| %>
<td><%= p.offc_addr %></td>
<% end %>
</tr>

Ruby on Rails form building simplification

thanks for taking the time to read this.
I'm trying to build a form that accepts multiple members. It starts off with 3 members and then there's a javascript button that adds a member, with a maximum of 100 members. The only way I can figure out how to do it is by hard coding all the form elements as below 1..100 (I only showed 1-4) and then hiding all the extras. The javascript button then just displays the next element. Is there a way I can generate the form element in the javascript? Or is there a way to use a loop to create the 100 hard coded elements?
<tr id="member_1">
<td></td>
<td class="field"><%= text_field(:members, :member_1_name, :value=>#members[:member_1_name]) %></td>
<td class="field"><%= text_field(:members, :member_1_number, :value=>#members[:member_1_number]) %></td>
</tr>
<tr>
<td></td>
<td class="heading">Member Names</td>
<td></td>
</tr>
<tr id="member_2">
<td></td>
<td class="field"><%= text_field(:members, :member_2_name, :value=>#members[:member_2_name]) %></td>
<td class="field"><%= text_field(:members, :member_2_number, :value=>#members[:member_2_number]) %></td>
</tr>
<tr id="member_3">
<td></td>
<td class="field"><%= text_field(:members, :member_3_name, :value=>#members[:member_3_name]) %></td>
<td class="field"><%= text_field(:members, :member_3_number, :value=>#members[:member_3_number]) %></td>
</tr>
<tr id="member_4" style="display:none">
<td></td>
<td class="field"><%= text_field(:members, :member_3_name, :value=>#members[:member_3_name]) %></td>
<td class="field"><%= text_field(:members, :member_3_number, :value=>#members[:member_3_number]) %></td>
</tr>
Thanks Again! Let me know if something isn't clear and whatnot
This sort of functionality is covered in episodes 196 & 197 of RailsCasts
Nested Model Forms Part 1 | Nested Model Forms Part 2
You should create only first member and put hidden div with template on a page. Javascript button should use this template and insert new field with it. See for example: http://embeddedjs.com/

Change table row using Rails Ajax

I've a simple page with link_to_remote Rails Ajax function and HTML table.
I'd like to change row of the table when click that link.
This is my html.
<table border="1">
<tr>
<td><div id="ajax_result_1">1</div></td>
<div id="ajax_result_2"><td>2</td></div>
</tr>
<div id="ajax_result_3">
<tr>
<td>3</td>
<td>4</td>
</tr>
</div>
</table>
And this is my code.
<%= link_to_remote 'Change', :update => "ajax_result_1", :url => "change_path" %>
change action just render simple text.
When I use ajax_result_1 for :update, it worked okay.
But, not for ajax_result_2 and ajax_result_3.
Is there a way to solve this? I want to replace row of the table.
<div id="ajax_result_2"><td>2</td></div>
this should be
<td><div id="ajax_result_2">2</div></td>
and
<div id="ajax_result_3">
<tr>
<td>3</td>
<td>4</td>
</tr>
</div>
should be
<tr id="ajax_result_3">
<td>3</td>
<td>4</td>
</tr>
you cann't use <div> tag in table directly if you want to use <div> you have to use it in the <td> only.

Resources