Displaying models as a list of a particular attributes - ruby-on-rails

I have a contacts model, with an attribute :area. I'd like to display one page (/listarea) as a list of all the areas. I have this part working
In contacts_controller.rb
def listarea
#listarea = Contact.order(:area).uniq.pluck(:area)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contacts }
end
end
And the listarea.html.erb
<table class="table table-striped table-hover">
<% #listarea.each do |area| %>
<tr class="tablerow">
<td><%= link_to area, :action => :areacontact, :area => area %></td>
</tr>
<% end %>
</table>
I'd like to be able to click on the area and lead to another page (areacontact) which will show a full list of all the contacts in that :area. This part is not working.
In contacts_controller.rb I have
def areacontacts
#contacts = Contact.order(:name).find_all_by_area(params[:area])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contacts }
end
end
And in areacontact.html.erb I have
<% #contacts.each do |contact| %>
Hello
<% end %>
The error when I view /areacontact is
ActionView::Template::Error (undefined method `each' for nil:NilClass):
Can anyone help?

Don't use <%= link_to area, :action => :areacontact, :area => area %> instead of use the path like areacontact_path check the proper path using rake routes. and
In the line #contacts = Contact.order(:name).find_all_by_area(params[:area]) seems like no attributes are passing properly pleas check what are the params you are getting in the action.

In your contacts_controller.rb, you need some tweaks when u have nothing to show in the view. I mean when your database contacts tables is empty.
So you can do like this in contacts_controller.rb
def areacontacts
#contacts = Contact.order(:name).find_all_by_area(params[:area]) rescue []
.....
...
end
You got error because of #contacts is not any result from your find_all_by_area query.
Also you can check nil in areacontact.html.erb before lopping #contacts like this:
<% if #contacts.present %>
<% #contacts.each do |contact| %>
Hello
<% end %>
<% end %>

Related

Loop thru values code

This is what I’m trying to do:
When an order is created, click view link and and get redirected to the show page which contains the invoice. I'm using the below code to loop thru values in the invoice. But its not working correctly, all invoices are showing up instead of only the selected one.
I already tried deleting the <% #orders.each do |order| %> but without any luck.
What am I missing here? Any idea?
<% #orders.each do |order| %>
<% order.line_items.each do |line_item| %>
Order #<%= line_item.order_id %>
<%= order.first_name %> <%= order.last_name %>
<%= line_item.product.title %>
<%= number_to_currency line_item.product.price %>
<%= line_item.quantity %>
<%= number_to_currency line_item.total_price %>
<% end %>
<% end %>
Update 1
route.rb: resources :orders, only: [:index, :new, :create, :show]
I don't have an invoice controller, everything is going thru the orders controller.
def show
#orders = Order.all
end
def new
#cart = current_cart
if #cart.line_items.empty?
redirect_to root_url, notice: "Your cart is empty"
return
end
#order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #order }
end
end
def create
#order = Order.new(order_params)
#order.add_line_items_from_cart(current_cart)
#order.user_id = current_user.id
if #order.save
if #order.process
redirect_to root_path, notice: "Successfully charged."
and
return
end
end
render 'new'
end
Change the method In Controller to
def show
#order = Order.find(params[:id])
end
and in views remove
<% #orders.each do |order| %>
and call the order attributes by
<% #order.line_items.each do |line_item| %>
Order #<%= line_item.order_id %>
<%= #order.first_name %> <%= #order.last_name %>
<%= line_item.product.title %>
<%= number_to_currency line_item.product.price %>
<%= line_item.quantity %>
<%= number_to_currency line_item.total_price %>
<% end %>
you were showing all the orders instead you only need to show order that got created in latest.
The Show method needs to look like this
def show
#order = Order.find(params[:id])
end
Make sure the route has the id in it, it should look like this where ":id" is a number (most likely)
/orders/:id
If the route doe snot look like that change the route in the link to that,
probably something like the params[:id] bit is grabbing that id from the route and that is how it finds that specific order.
In your view you will not need to do the each loop. You will be able to use the #order variable you create, so your view would look like this
<%= #order.first_name %> <%= #order.last_name %>
#Theopap
The issue currently is the show method which returns the all the orders found in the Order database, refactor the show method to look for orders of a specific id, therefore your show method should look something like this:
Current show should become index action
def index
#orders = Order.all
end
This will get the order id from the route, so the
def show
#order = Order.find(params[:id])
end
Routes
Something like this should done with your routes so that your params[id].
get ‘\order\:id’, to:‘order#show’
Better still use the option below to generate the 7 default rails actions.e.g. index, show, create etc.
resources orders (http://guides.rubyonrails.org/v2.3/routing.html)
Could you please display your show method, the issue is likely to be from there. Use the ruby on rails debugger in the mean time, to ensure that #orders contains the invoice information for just the order placed.
try this: <%= debug #orders %>

Best in place gem not updating values - rails 4

so i have installed best in place gem in a rails 4 environment and initialised it correctly. (i can click on the name field and the box becomes editable).
I've this code in my admin_namespaced user controller
class Admin::UsersController < Admin::BaseController
def index
#users = User.all
# #columns = User.column_names
end
def show
#user = User.find(params[:id])
end
def update
#user = User.find params[:id]
respond_to do |format|
if #user.update_attributes(user_params)
format.html { redirect_to(user, :notice => 'User was successfully updated.') }
format.json { respond_with_bip(#user) }
else
format.html { render :action => "index" }
format.json { respond_with_bip(#user) }
end
end
end
private
def user_params
params.require(:user).permit(:name,:email,:password,:password_confirmation)
end
end
and basically i want to use it in conjuction with rails datatables gem that i successfully setup, to inline-edit corresponding fields.
this is the html.erb code in my user index view
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= link_to "Back", admin_path %>
<table class="display responsive no-wrap text-center" id="usertableadmin">
<thead>
<tr>
<th>id</th>
<th>Username</th>
<th>Email</th>
<th>Activated?</th>
<th>Admin?</th>
</tr>
</thead>
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= best_in_place user, :name%></td>
<td><%= user.email %></td>
<td><%= user.activated %></td>
<td><%= user.admin %></td>
</tr>
<% end %>
</tbody>
</table>
here is what the html code looks like on the tag that has the best_in_place initialization.
<span data-bip-type="input" data-bip-attribute="name" data-bip-object="user" data-bip-original-content="Example User" data-bip-url="/users/1" data-bip-value="Example User" class="best_in_place" id="best_in_place_user_1_name">Example User</span>
I dont know for sure but for some reason the fields do not get updated. When i click to change the name it gets reverted to the previous one.
I dont know if its because i have a namespace, admin/users or its because its the index action and not the show action.
any insight is welcome.
I've found the solution,
it seems the error was the update url it was wrong because of the namespace.
What i had to do, was to include url parameter like below
<td><%= best_in_place user, :name, url: "users/#{user.id}" %></td>

Job has many Applicants.. However, I can not get Job parameters to come over to the Applicant Form

User can view jobs and then fill out application. I.E. job has many applications. When creating new application, the appropriate job attributes are not coming over to the form.
I do have the relationship set up correctly. I am not correctly passing the parameters. When I create a new application, it does find the job_id. However, when on the application form, I would like more of the job attributes to show up, such as job.title. I think it is an issue with my controller.
applications_controller.rb:
class ApplicationsController < ApplicationController
before_action :set_application, only: [:show, :edit, :update, :destroy]
# GET /applications
# GET /applications.json
def index
#applications = Application.all
end
# GET /applications/1
# GET /applications/1.json
def show
end
# GET /applications/new
def new
#application = Application.new
#job = Job.find(params[:job_id])
end
# GET /applications/1/edit
def edit
end
# POST /applications
# POST /applications.json
def create
#job = Job.find(params[:job_id])
#application = Application.new(application_params)
#application.job = #job
name = #job.title
respond_to do |format|
if #application.save
format.html { redirect_to #application, notice: 'Application was successfully created.' }
format.json { render :show, status: :created, location: #application }
else
format.html { render :new }
format.json { render json: #application.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /applications/1
# PATCH/PUT /applications/1.json
def update
respond_to do |format|
if #application.update(application_params)
format.html { redirect_to #application, notice: 'Application was successfully updated.' }
format.json { render :show, status: :ok, location: #application }
else
format.html { render :edit }
format.json { render json: #application.errors, status: :unprocessable_entity }
end
end
end
# DELETE /applications/1
# DELETE /applications/1.json
def destroy
#application.destroy
respond_to do |format|
format.html { redirect_to applications_url, notice: 'Application was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_application
#application = Application.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def application_params
params[:application]
end
def job_params
params.require(:job).permit(:title, :description, :status)
end
end
This is the table I have in jobs/index.html.erb --> It has the link that launches new application... Am I supposed to be passing in local variables here?
<table class="table table-striped">
<thead>
<tr>
<th colspan="3"> Current Job Openings</th>
</tr>
</thead>
<tbody>
<% #jobs.each do |job| %>
<tr>
<td><%= job.title %></td>
<td><%= job.description %></td>
<td><button type="button" class="newave-button medium grey move pull-right" style="color: white"><%= link_to 'Online Application', new_job_application_path(job) %></button></td>
</tr>
<% end %>
</tbody>
</table>
This actually launches applications/new.html.erb which simply contains a partial to render a new form:
<%= render 'form' %>
And finally, here is my applications/_form.html.erb that is being rendered. I would like to relate the job specific info at the top of the page..
<%= link_to 'Back', jobs_path, class: "newave-button medium grey move" %>
<%= form_for [#job, #application] do |f| %>
<% if #application.errors.any? %>
<div id="error_explanation">
<h3><%= pluralize(#application.errors.count, "error") %> prohibited this application from being saved:</h3>
<ul>
<% #application.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container small-width" id="application-form">
<h2>Personal Information</h2>
<%= params %>
<div class="field">
<%= f.label :full_name, "Name" %><br>
<%= f.text_field :full_name%>
</div>
<div class="actions">
<%= f.submit "Submit Form", class: 'btn btn-primary' %>
</div>
<% end %>
To summarize, you're attempting to add the job title in to the Application form / parameter map when creating an Application object so that the Application has the job title in it as well.
Based on our discussion and your description, the job_title field is an attribute of the Job model, and has nothing to do directly with the application itself. The association between Application and Job is made through a column on the Application table called (unless you deliberately changed the name) job_id. If you examine the action URL of the rendered form, it already contains the job_id, which is available to rails when you submit the form in the parameter map. As you're already doing in the create action in the controller, you can access it via params[:job_id]. Basically, you've got the right idea create action.
Think of it this way; the only parameters that are necessary in the Application form (and consequently, in the params), are the ones that are directly relevant for the Application object. Job id is relevant because you need that to know which Job object you're associating, but job title is not, because you can get it through the associated job.
Regarding your question on how to access the job title in the new form for display purposes, as mentioned, you've already set up a #job variable in the controller. You can simply access the job title like so: #job.title. The reason why #application.job.title didn't work is because we haven't associated it yet. Remember that the new and create actions are completely separate, and its in the create action where you'll be making that association.

Link_to create with parameter before - ForbiddenAttributesError now

What I Want:
I need in a view a button or a link (it doesn't matter) to the create action of Reservation controller and to give it a parameter too.
And resolve the ForbiddenAttributesError that now gives me.
Here are my model and controller:
Reservation model
class Reservation < ActiveRecord::Base
belongs_to :user
belongs_to :dinner
end
Reservation controller
class ReservationsController < ApplicationController
load_and_authorize_resource
def show
#reservations = Reservation.joins(:user).where('dinner_id' => params[:dinner_id]).select("users.*,reservations.*")
#dinnerid = params[:dinner_id]
respond_to do |format|
format.html
format.json { render :json => #reservations }
end
end
def create
#reservation = Reservation.new(params[:reservation])
#reservation.user_id = current_user.id
respond_to do |format|
if #reservation.save
format.html { redirect_to #reservation, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :show }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def reservation_params
params.require(:reservation).permit(:dinner_id)
end
end
EDIT: After the suggestion of #Rahul Singh this is my actual code with relative error:
<p id="notice"><%= notice %></p>
<table>
<thead>
<tr>
<th>Id</th>
<th>User id</th>
<th>Dinner id</th>
<th>User email</th>
<th>User name</th>
</tr>
</thead>
<tbody>
<% #reservations.each do |reservation| %>
<tr>
<td><%= reservation.id %></td>
<td><%= reservation.user_id %></td>
<td><%= reservation.dinner_id %></td>
<td><%= reservation.user.email %></td>
<td><%= reservation.user.name %></td>
</tr>
<% end %>
</tbody>
</table>
<br/>TRY 00a <br/>
<%= form_for(Reservation.new) do |f| %>
<%= f.hidden_field( :dinner_id, :value => #dinnerid.to_s) %>
<%= f.submit "Join1" %>
<% end %>
<br/> !!!!!!!!!!ERROR : ActiveModel::ForbiddenAttributesError
<br/>TRY 00b <br/>
<%= link_to "Join1", reservations_path(dinner_id:#dinnerid.to_s), method: :post %>
<br/> !!!!!!!!!!ERROR : param is missing or the value is empty: reservation
I provide a sreenshot for the error :
Error of the form : https://www.dropbox.com/s/i2x1m520ptqdj56/createReservationForm.jpg
Error of the link_to : https://www.dropbox.com/s/8xjwee5oo7q6uhk/createReservationLink_to.jpg
This should work
<%= form_for(Reservation.new) do |f| %>
<%= f.hidden_field( :dinner_id, :value => #dinnerid.to_s) %>
<%= f.submit "Join1" %>
<% end %>
clicking on Join1 button will submit form to ReservationsController create action.
and with link try this
<%= link_to "Join1", reservations_path(dinner_id:#dinnerid.to_s), method: :post %>
for above to work,add following in your routes.rb
resources :reservations
Change this line -> #reservation = Reservation.new(params[:reservation])
To this -> #reservation = Reservation.new reservation_params
and try again ;).
I'm wondering if it wouldn't be better to have your reservation routes as a nested resource of dinners.
It seems reservations can't exist without a dinner, so I'd make that explicit like this:
# config/routes.rb
resources :dinners do
resources :reservations
end
Run rake routes to see how this would change the routes.
You'd now have the dinner id passed along:
# app/views/dinners/show.html.erb
<%= button_to 'Reserve this dinner', dinner_reservations_path(#dinner) %>
The button would route to the create action because a button's default HTTP method is POST.
# app/controllers/reservations_controller.rb
class ReservationsController < ApplicationController
before_action :set_dinner
def create
#dinner.reservations.create! user: current_user
# would render reservations/create.html.erb
end
private
def set_dinner
#dinner = Dinner.find(params[:id])
end
end
This doesn't fix your immediate problem of just getting that link to work. But I think you'd be a lot better served structuring your app more like the above going forward.
Full disclosure: the person who asked this question contacted me on twitter personally, so I took some liberties in answering this question with a more general design suggestion.
I'm not sure this is the "best" approach but I think its the easiest one.
You could do something with string interpolation:
a href="/reservations?dinner=#{dinner.id}" Join
then you could get the paramter with
params[:dinner]

undefined method `errors' for nil:NilClass

Here is my Edited details:
I have my controller like,
class Enr::Rds::SurvRdsapXrefsController < Enr::Controller
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
end
def show
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def edit
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.find(params[:id])
end
def create
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new(params[:enr_rds_surv_rdsap_xref])
respond_to do |format|
if #enr_rds_surv_rdsap_xref.save
format.html { redirect_to :enr_rds_surv_rdsap_xrefs, notice: "Survey link was successfully created." }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref, status: :created, location: #enr_rds_surv_rdsap_xref }
else
format.html { render action: "new" }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref.errors, status: :unprocessable_entity }
end
end
end
def update
end
def destroy
end
end
Here is my view form like
<%= form_for(#enr_rds_surv_rdsap_xref, :remote => true) do |f| %>
<% if #enr_rds_surv_rdsap_xref.errors.any? %>
<div id="error_explanation">
<div class="validate">
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>.
</div>
<ul>
<% #enr_rds_surv_rdsap_xref.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="control-group">
<%= f.label :section %><br />
<%= f.text_field :section %>
</div>
<%= f.submit %>
<% end %>
When i click the index page to create a new link, the index page showing error like
NoMethodError in Enr/rds/surv_rdsap_xrefs#index
undefined method `errors' for nil:NilClass
Thanks for the suppport and please suggest me to rectify the error. I am new to ROR. Thanks
Your error reveals that the rendering of the index template is causing the error, which means you're rendering the form for the new survey (the code snippet above) in the index template. This is fine, but if you're going to do that, you'll have to instantiate a new survey in index, as well as in new.
At the simplest, you could just copy the code in new to index:
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
To keep your code a bit DRYer you might change where the new instance is created. A pattern you'll often see is something similar to:
before_filter :build_record, :only => [:new, :index]
protected
def build_record
#survey = YourSurvey.new
end
This way you don't even need to write the new/index methods if you don't have any other logic.
Do you also set #survey in the new action in your controller? The error means that when the view is rendered #survey is nil, so there must be a problem with setting that instance variable.
Do you get the error when you go to the 'new' view or when you try to submit the form (create)?
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>
This line of the code is the problem. You are lacking a "(" between the pluralize and the #enr...
Explained: RoR thinks that the object is: pluralize#enr... instead of the # All alone, and he has no errors for this kind of object.

Resources