Rails Export multiple tables to csv - ruby-on-rails

Hi I have a simple rails application that has two models Equipment_Types & Tasks
Each equipment type has many tasks. When I export to csv file I would like to export the name of the equipment type, the task name and the associated schedule. Basically every thing that is displayed on equipment_type/show.html.erb
<p id="notice"><%= notice %></p>
<div class="row">
<table class="table table-bordered">
<thead>
<tr>
<th class="align-middle" rowspan="2">Equipment</th>
<th class="align-middle" rowspan="2">Task</th>
<th class="text-center" colspan="4">Frequency</th>
</tr>
<tr>
<th class="text-center">M</th>
<th class="text-center">Q</th>
<th class="text-center">B</th>
<th class="text-center">A</th>
</tr>
</thead>
<tbody>
<tr>
<% if #taskcount > 3 %>
<td class="text-center bottomtotop" rowspan="0"><%= link_to #equipment_type.name, edit_equipment_type_path(#equipment_type) %></td>
<% else %>
<td class="text-center" rowspan="0"><%= link_to #equipment_type.name, edit_equipment_type_path(#equipment_type) %></td>
<% end %>
</tr>
<% #equip_tasks.each do |task| %>
<tr>
<td><%= link_to task.name, task %></td>
<td class="text-center"><%= if task.monthly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.quarterly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.sixmonthly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.annually then 'x' else ' ' end %></td>
</tr>
<% end %>
<div class="collapse" id="collapsenewline">
</div>
</tbody>
</table>
</div>
<div class="row">
<div class="col-sm">
<%= link_to 'Add Task', new_task_path(#equipment_type), class: 'btn btn-dark' %>
</div>
<div class="col-sm">
<%= link_to 'Back', equipment_types_path, class: 'btn btn-dark' %>
</div>
<div class="col-sm">
<button class="btn btn-dark" type="button" data-toggle="collapse" data-target="#collapsedownload" aria-expanded="false" aria-controls="collapseExample">
Download
</button>
</div>
</div>
<div class="row">
<div class="col-sm">
</div>
<div class="col-sm">
</div>
<div class="col-sm">
<div class="collapse" id="collapsedownload">
<div class="card card-body">
<h3>Download File</h3>
<%= link_to "csv", equipment_types_path(format: "csv"), class: 'btn btn-dark' %>
<br>
<%= link_to "pdf", equipment_types_path(format: "pdf"), class: 'btn btn-dark' %>
<br>
<%= link_to "word", equipment_types_path(format: "word"), class: 'btn btn-dark' %>
</div>
</div>
</div>
</div>
equipment_type Model
class EquipmentType < ApplicationRecord
has_many :tasks
accepts_nested_attributes_for :tasks
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
EquipmentType.create! row.to_hash
end
end
def self.to_csv
CSV.generate do |csv|
csv << column_names
all.each do |equipmenttype|
csv << equipmenttype.attributes.values_at(*column_names)
end
end
end
end
equipment_types Controller
class EquipmentTypesController < ApplicationController
before_action :set_equipment_type, only: [:show, :edit, :update, :destroy]
before_action :set_task, only: [:show]
# GET /equipment_types
# GET /equipment_types.json
def index
#equipment_types = EquipmentType.all
respond_to do |format|
format.html
format.csv { send_data #equipment_types.to_csv }
end
end
# GET /equipment_types/1
# GET /equipment_types/1.json
def show
#equipment_type = EquipmentType.find_by(id: params[:id])
#tasks = Task.all
#equip_tasks = #equipment_type.tasks.all
#taskcount = #equip_tasks.count
respond_to do |format|
format.html
format.csv { send_data text: #equip_tasks.to_csv }
end
end
# GET /equipment_types/new
def new
#equipment_type = EquipmentType.new
end
# GET /equipment_types/1/edit
def edit
end
# POST /equipment_types
# POST /equipment_types.json
def create
#equipment_type = EquipmentType.new(equipment_type_params)
respond_to do |format|
if #equipment_type.save
format.html { redirect_to #equipment_type, notice: 'Equipment type was successfully created.' }
format.json { render :show, status: :created, location: #equipment_type }
else
format.html { render :new }
format.json { render json: #equipment_type.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /equipment_types/1
# PATCH/PUT /equipment_types/1.json
def update
respond_to do |format|
if #equipment_type.update(equipment_type_params)
format.html { redirect_to #equipment_type, notice: 'Equipment type was successfully updated.' }
format.json { render :show, status: :ok, location: #equipment_type }
else
format.html { render :edit }
format.json { render json: #equipment_type.errors, status: :unprocessable_entity }
end
end
end
def import
EquipmentType.import(params[:file])
redirect_to equipment_type_path, notice: "Equipment Type Added Successfully"
end
# DELETE /equipment_types/1
# DELETE /equipment_types/1.json
def destroy
#equipment_type.destroy
respond_to do |format|
format.html { redirect_to equipment_types_url, notice: 'Equipment type was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_equipment_type
#equipment_type = EquipmentType.find(params[:id])
end
def set_task
#task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def equipment_type_params
params.require(:equipment_type).permit(:name, task: [])
end
end
Task Model
class Task < ApplicationRecord
belongs_to :equipment_type
end
Tasks Controller
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
# GET /tasks
# GET /tasks.json
def index
#tasks = Task.all
end
# GET /tasks/1
# GET /tasks/1.json
def show
end
# GET /tasks/new
def new
#task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks
# POST /tasks.json
def create
#task = Task.new(task_params)
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tasks/1
# PATCH/PUT /tasks/1.json
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def task_params
params.require(:task).permit(:name, :monthly, :quarterly, :sixmonthly, :annually, :equipment_type_id)
end
end

This should get you started:
You merely need to just append the attributes to the array.
Instead of,
csv << equipmenttype.attributes.values_at(*column_names)
Drop in this (or similar) (note: this is resource-intensive so you'll want to trim it down especially if you have lots of tasks)
def csv_attributes
{
tasks: self.tasks.all.map(&:attributes).map(&:values),
id: self.id
}
end
and then
csv << equipmenttype.csv_attributes

Related

has_many :through Ruby on Rails

I want to set a reservation based on user_id and trip_id . but i dont know how to . I tried to make a form in trips/show
What i want is to see the full list of trips and select one and the form below should save the user_id and trip_id in databse. Idk if i can send data like this because i wrote the form in trips which has his own model of Trip.
Can someone explain how has_many :through concept work. The problem is that idk if i can make another controller to save ids or i can do it in trip controllers. please help
<h1>Trips</h1>
<table class="table ">
<thead class="thead-dark">
<tr>
<th>Locatie</th>
<th>Descriere</th>
<th colspan="3"></th>
</tr>
</thead>
<%= Current.user.admin %>
<% if Current.user.admin == true %>
<tbody>
<% #trips.each do |trip| %>
<tr>
<td><%= trip.locatie %></td>
<td><%= trip.descriere %></td>
<td class="text-center"><%= link_to 'Select', trip , class: "btn btn-secondary "%></td>
<td class="text-center"><%= link_to 'Edit', edit_trip_path(trip) ,class: "btn btn-secondary " %></td>
<td class="text-center"><%= link_to 'Destroy', trip, method: :delete, data: { confirm: 'Are you sure?' } ,class: "btn btn-secondary "%></td>
</tr>
<% end %>
</tbody>
<% else %>
<tbody>
<% #trips.each do |trip| %>
<tr>
<td><%= trip.locatie %></td>
<td><%= trip.descriere %></td>
<td class="text-center"><%= link_to 'Select', trip , class: "btn btn-secondary "%></td>
</tr>
<% end %>
</tbody>
<% end %>
</table>
<br>
<%= link_to 'New Trip', new_trip_path ,class:"btn btn-secondary"%>
<p>
<strong>Locatie:</strong>
<%= #trip.locatie %>
</p>
<p>
<strong>Descriere:</strong>
<%= #trip.descriere %>
</p>
<%= #trip.id %>
<%= Current.user.id %>
<br/>
<%= form_with model: #reservation, local: true , url: save_reservation_path do |form| %>
<%= form.text_field :user_id , value: #trip.id %>
<%= form.text_field :trip_id , value: Current.user.id%>
<%= form.submit %>
<% end %>
<%= link_to 'Back', trips_path ,class: "btn btn-secondary "%>
Trip controller
class TripsController < ApplicationController
before_action :set_trip, only: %i[ show edit update destroy ]
# GET /trips or /trips.json
def index
#trips = Trip.all
end
# GET /trips/1 or /trips/1.json
def show
end
# GET /trips/new
def new
#trip = Trip.new
end
# GET /trips/1/edit
def edit
end
# POST /trips or /trips.json
def create
#trip = Trip.new(trip_params)
respond_to do |format|
if #trip.save
format.html { redirect_to trip_url(#trip), notice: "Trip was successfully created." }
format.json { render :show, status: :created, location: #trip }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #trip.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /trips/1 or /trips/1.json
def update
respond_to do |format|
if #trip.update(trip_params)
format.html { redirect_to trip_url(#trip), notice: "Trip was successfully updated." }
format.json { render :show, status: :ok, location: #trip }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #trip.errors, status: :unprocessable_entity }
end
end
end
# DELETE /trips/1 or /trips/1.json
def destroy
#trip.destroy
respond_to do |format|
format.html { redirect_to trips_url, notice: "Trip was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_trip
#trip = Trip.find(params[:id])
end
# Only allow a list of trusted parameters through.
def trip_params
params.require(:trip).permit(:locatie, :descriere)
end
end
Reservation controller
class ReservationsController < ApplicationController
# GET /reservations or /reservations.json
def index
#reservations = Reservation.all
end
# GET /reservations/1 or /reservations/1.json
def show
#reservations = Reservation.all
end
# GET /reservations/new
def new
#reservation = Reservation.new
end
# GET /reservations/1/edit
def edit
end
# POST /reservations or /reservations.json
def create
#reservation = Reservation.new(reservation_params)
respond_to do |format|
if #reservation.save
format.html { redirect_to reservation_url(#reservation), notice: "Reservation was successfully created." }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reservations/1 or /reservations/1.json
def update
respond_to do |format|
if #reservation.update(reservation_params)
format.html { redirect_to reservation_url(#reservation), notice: "Reservation was successfully updated." }
format.json { render :show, status: :ok, location: #reservation }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reservations/1 or /reservations/1.json
def destroy
#reservation.destroy
respond_to do |format|
format.html { redirect_to reservations_url, notice: "Reservation was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_reservation
#reservation = Reservation.find(params[:id])
end
# Only allow a list of trusted parameters through.
def reservation_params
params.require(:reservation_params).permit(user_id: [], trip_id: [])
end
end

Edit field is blank (rails 6.1.4)

I am new to Ruby on Rails and we have a project called TaskApp.
It that has 2 models: Category, Task.
Category has many tasks and Task belongs to Category.
When I go from tasks index to edit task, I am getting the edit view with blank fields.
Please find relevant codes below.
I am grateful for any advise to get me to resolve this.
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'registrations' }
get 'home/index'
root 'home#index'
resources :categories do
resources :tasks
end
end
tasks_controller.rb
class TasksController < ApplicationController
before_action :authenticate_user!
before_action :set_category, except: %i[index edit]
before_action :set_task, only: %i[show update destroy]
def index
#tasks = Task.where(user_id: current_user.id, deadline: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).order(priority: :asc)
end
def new
#task = #category.tasks.build
end
def show
end
def create
#task = #category.tasks.create(task_params.merge(user_id: current_user.id))
respond_to do |format|
if #task.save
format.html { redirect_to #task.category, notice: "Task was successfully created." }
format.json { render :show, status: :created, location: #task.category }
else
format.html { redirect_to #task.category, notice: "Invalid inputs." }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def edit
#category = Category.find(params[:category_id])
#task = #category.tasks.find(params[:id])
end
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task.category, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to #task.category, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_category
#category = Category.find(params[:category_id])
end
def set_task
#task = #category.tasks.find(params[:id])
end
def task_params
params.require(:task).permit(:name, :description, :priority, :deadline, :completed, :user_id, :category_id)
end
end
.../tasks/views/edit.html.erb
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Priority</th>
<th>Deadline</th>
<th>Completed</th>
<th>Action</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<% #category.tasks.each do |task| %>
<% if task.user_id == current_user.id %>
<tr>
<td><%= link_to task.name, [task.category, task] %></td>
<td><%= task.description %></td>
<td><%= task.priority %></td>
<td><%= task.deadline.strftime("%d %b %Y") %></td>
<td><%= task.completed %></td>
<td><%= link_to 'Edit', edit_category_task_path(task.category, task) %></td>
<td><%= link_to 'Delete', [task.category, task],
method: :delete,
data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
</div>

How to show nested database

Hello I have a nested database "processing" which belongst to "shopping_process". However I want somehow to see the messages, which are saved in processing. How can I do that? If I go to http://localhost:3000/processings/index the Error: Couldn't find Processing with 'id'=index appears. Has somebody an idea?
processings_controller.rb
class ProcessingsController < ApplicationController
before_action :set_processing, only: [:show, :edit, :update, :destroy]
# GET /processings
# GET /processings.json
def index
#processings = Processing.all
end
# GET /processings/1
# GET /processings/1.json
def show
end
# GET /processings/new
def new
#processing = Processing.new
end
# GET /processings/1/edit
def edit
end
# POST /processings
# POST /processings.json
def create
#processing = Processing.new(processing_params)
respond_to do |format|
if #processing.save
format.html { redirect_to #processing, notice: 'Processing was successfully created.' }
format.json { render :show, status: :created, location: #processing }
else
format.html { render :new }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /processings/1
# PATCH/PUT /processings/1.json
def update
respond_to do |format|
if #processing.update(processing_params)
format.html { redirect_to #processing, notice: 'Processing was successfully updated.' }
format.json { render :show, status: :ok, location: #processing }
else
format.html { render :edit }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /processings/1
# DELETE /processings/1.json
def destroy
#processing.destroy
respond_to do |format|
format.html { redirect_to processings_url, notice: 'Processing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_processing
#processing = Processing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def processing_params
params.require(:processing).permit(:shopping_process_id, :shopping_list_id, :accepted, :responded, :message)
end
end
view/processings/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Processings</h1>
<table>
<thead>
<tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #Processing.all.each do |processing| %>
<tr>
<td><%= link_to 'Show', processing %></td>
<td><%= link_to 'Edit', edit_processing_path(processing) %></td>
<td><%= link_to 'Destroy', processing, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Processing', new_processing_path %>
models/processing.rb
class Processing < ApplicationRecord
# db associations
belongs_to :shopping_process
belongs_to :shopping_list
# validations
validates :shopping_list, :presence => true
end
Now here comes the code for the database "shopping_processes"
shopping_processes_controller.rb
class ShoppingProcessesController < ApplicationController
load_and_authorize_resource
layout 'shopping_process', only: [:shopper_show, :senior_show]
# GET /shopping_processes/1
# GET /shopping_processes/1.json
def show
end
# POST /shopping_processes
# POST /shopping_processes.json
def create
#shopping_process.status =nil
#shopping_process.processed = nil
puts params.inspect
respond_to do |format|
if #shopping_process.save
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully created.' }
format.json { render :show, status: :created, location: #shopping_process }
else
format.html { render :new }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_processes/1
# PATCH/PUT /shopping_processes/1.json
def update
respond_to do |format|
if #shopping_process.update(shopping_process_params)
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully updated.' }
format.json { render :show, status: :ok, location: #shopping_process }
else
format.html { render :edit }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_processes/1
# DELETE /shopping_processes/1.json
def destroy
#shopping_process.destroy
respond_to do |format|
format.html { redirect_to shopping_processes_url, notice: 'Shopping process was successfully destroyed.' }
format.json { head :no_content }
end
end
def shopper_show
#shopping_process = ShoppingProcess.find(params[:id])
#users = {}
first = true
#shopping_process.shopping_lists.each do |shopping_list|
user = shopping_list.user
#users[user.id] = {color: (first ? 'blue' : 'yellow'), name: user.firstname + ' ' + user.lastname}
first = false
end
end
def senior_show
#shopping_process = ShoppingProcess.find(params[:id])
#shopping_process.shopping_lists.each do |shopping_list|
#if shopping_list.user == current_user
# #shopping_list = shopping_list
#end
#shopping_list = shopping_list
#to show the correct shopping list uncomment the block above and remove the declartion underneath it
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shopping_process
#shopping_process = ShoppingProcess.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def shopping_process_params
params.require(:shopping_process).permit(:user_id, :status, :appointed, :processed, :shopping_list_id, processings_attributes: [ :shopping_list_id, :message ])
end
end
views/shopping_processes/form.html.erb
<%= form_for(shopping_process) do |f| %>
<% if shopping_process.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(shopping_process.errors.count, "error") %> prohibited this shopping_process from being saved:</h2>
<ul>
<% shopping_process.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :appointed %>
<%= f.datetime_select :appointed %>
</div>
<div class="field">
<%= f.label :shopper %>
<%= f.text_field :user_id, value: current_user.id, :readonly => true%>
</div>
<div class="field">
<%= f.label :shopping_list_id %>
<%= f.select :shopping_list_id, ShoppingList.accessible_by(current_ability).map{ |sl| [sl.name, sl.id] } %>
</div>
<!-- SUB FORM FOR NESTED RESOURCE : PROCESSINGS -->
<%= f.fields_for :processings, #shopping_process.processings.build do |ff| %>
<div>
<%= ff.label :Begleiter %>
<%= ff.select :shopping_list_id, ShoppingList.all.map{ |sl| [sl.user.firstname, sl.id]} , {:prompt => true} %>
</div>
<div>
<%= ff.label :message %>
<%= ff.text_field :message%>
</div>
<% end %>
<!-- Submit-->
<div class="actions">
<%= f.submit %>
</div>
<% end %>

CRUD db entity from other controller

I want to create, edit and delete db entity from other controller than generated by scaffold. I want to have validation, create and deletion without redirection. I don't want to use generated controller because i want to create at least 2 types of entities from one controller.
For now i have create without redirect but i don't have notification about entity creation.
This controller should support crud operations:
class SmartHomeController < ApplicationController
layout 'smart_home'
def index
#name = 'Home';
end
def settings
#name = 'Settings';
#place = Place.new;
#all_places = Place.all;
respond_to do |format|
if #place.save
format.html { redirect_to #place, :notice => 'A was successfully created.' }
else
# render new with validation errors
format.html { render :action => "settings" }
end
end
end
end
scaffold generated controller:
class PlacesController < ApplicationController
before_action :set_place, only: [:show, :edit, :update, :destroy]
# GET /places
# GET /places.json
def index
#places = Place.all
end
# GET /places/1
# GET /places/1.json
def show
end
# GET /places/new
def new
#place = Place.new
end
# GET /places/1/edit
def edit
end
# POST /places
# POST /places.json
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to smart_home_settings_path, notice: 'Place was successfully created.' }
format.json { render :show, status: :created, location: #place }
else
format.html { render :new }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /places/1
# PATCH/PUT /places/1.json
def update
respond_to do |format|
if #place.update(place_params)
format.html { redirect_to #place, notice: 'Place was successfully updated.' }
format.json { render :show, status: :ok, location: #place }
else
format.html { render :edit }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# DELETE /places/1
# DELETE /places/1.json
def destroy
#place.destroy
respond_to do |format|
format.html { redirect_to places_url, notice: 'Place was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_place
#place = Place.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def place_params
params.require(:place).permit(:name, :hw)
end
end
Could you guide me how to achieve that?
Edit. New code.
Page:
<div class="demo-cards mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet mdl-grid mdl-grid--no-spacing"
style="width: 420px">
<div class="demo-updates mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--12-col-desktop">
<div class="mdl-card__title mdl-card--expand mdl-color--teal-300">
<h2 class="mdl-card__title-text">All places</h2>
</div>
<div class="mdl-card__supporting-text mdl-color-text--grey-600">
<ul class="demo-list-item mdl-list">
<% #all_places.each do |place| %>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<%= place.name %>: <%= place.hw %> <%= link_to 'Destroy', place, controller: 'smart_home', action: 'delete_place', data: { confirm: 'Are you sure?' } %>
</span>
</li>
<% end %>
</ul>
</div>
</div>
</div>
<div class="demo-cards mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet mdl-grid mdl-grid--no-spacing"
style="width: 420px">
<div class="demo-updates mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--12-col-desktop">
<div class="mdl-card__title mdl-card--expand mdl-color--teal-300">
<h2 class="mdl-card__title-text">Create place</h2>
</div>
<div class="mdl-card__supporting-text mdl-color-text--grey-600">
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp create-place-table">
<%= form_for #place, url: smart_home_create_path do |f| %>
<tr>
<td>
<div class="mdl-textfield mdl-js-textfield">
<%= f.label :name, 'Name', class: 'mdl-textfield__label' %>
<%= f.text_field :name, class: 'mdl-textfield__input' %>
</div>
</td>
</tr>
<tr>
<td>
<div class="mdl-textfield mdl-js-textfield">
<%= f.label :hw, class: 'mdl-textfield__label' %>
<%= f.text_field :hw, class: 'mdl-textfield__input' %>
</div>
</td>
</tr>
<tr>
<td>
<%= f.submit "Create", class: 'mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect' %>
</td>
</tr>
<% end %>
</table>
</div>
</div>
</div>
Controller:
class PlacesController < ApplicationController
before_action :set_place, only: [:show, :edit, :update, :destroy]
# GET /places
# GET /places.json
def index
#places = Place.all
end
# GET /places/1
# GET /places/1.json
def show
end
# GET /places/new
def new
#place = Place.new
end
# GET /places/1/edit
def edit
end
# POST /places
# POST /places.json
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to smart_home_settings_path, notice: 'Place was successfully created.' }
format.json { render :show, status: :created, location: #place }
else
format.html { render :new }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /places/1
# PATCH/PUT /places/1.json
def update
respond_to do |format|
if #place.update(place_params)
format.html { redirect_to #place, notice: 'Place was successfully updated.' }
format.json { render :show, status: :ok, location: #place }
else
format.html { render :edit }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# DELETE /places/1
# DELETE /places/1.json
def destroy
#place.destroy
respond_to do |format|
format.html { redirect_to smart_home_settings_path, notice: 'Place was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_place
#place = Place.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def place_params
params.require(:place).permit(:name, :hw)
end
end
Deletion works but no confirm:
Page:
<%= link_to 'Destroy', delete_place_path(id: place.id), data: {:confirm => 'Are you sure?'}, :method => :delete %>
Controller:
def delete_place
place = Place.find(params[:id])
place.destroy
respond_to do |format|
format.html { redirect_to smart_home_settings_path, notice: 'Place was successfully destroyed.' }
format.json { head :no_content }
end
end
Routes:
get 'delete_place/:id' => 'smart_home#delete_place', as: :delete_place
Edit:
Javascript include was missed
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>

NoMethodError in Pages#dashboard

I am creating a dashboard for my app but when i want to display the reviews I get the NoMethodError although i have defined the variables in the controller. I am getting the error when I view the dashboard page. Here's my code
pages_controller.rb
class PagesController < ApplicationController
before_action :authenticate_user!, only: [:dashboard]
def about
end
def help
end
def contact
end
def dashboard
#user = current_user
#places = #user.places
#reviews = #user.reviews
end
end
reviews_controller.rb
class ReviewsController < ApplicationController
before_action :set_review, only: [:edit, :update, :destroy]
before_action :set_place
before_action :authenticate_user!
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews
# POST /reviews.json
def create
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.place_id = #place.id
#review.save
redirect_to place_path(#place)
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to #review, notice: 'Review was successfully updated.' }
format.json { render :show, status: :ok, location: #review }
else
format.html { render :edit }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1
# DELETE /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url, notice: 'Review was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
def set_place
unless #place = Place.where(id: params[:place_id]).first
redirect_to places_path, flash: {alert: "Place doesn't exists"}
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:comment,:rating)
end
end
places_controller.rb
class PlacesController < ApplicationController
before_action :set_place, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user! , except: [:index,:show]
# GET /places
# GET /places.json
def index
#places = Place.all
end
# GET /places/1
# GET /places/1.json
def show
#reviews = Review.where(place_id: #place.id)
end
# GET /places/new
def new
#place = Place.new
end
# GET /places/1/edit
def edit
end
# POST /places
# POST /places.json
def create
#place = Place.new(place_params)
#place.user_id = current_user.id
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render :show, status: :created, location: #place }
else
format.html { render :new }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /places/1
# PATCH/PUT /places/1.json
def update
respond_to do |format|
if #place.update(place_params)
format.html { redirect_to #place, notice: 'Place was successfully updated.' }
format.json { render :show, status: :ok, location: #place }
else
format.html { render :edit }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# DELETE /places/1
# DELETE /places/1.json
def destroy
#place.destroy
respond_to do |format|
format.html { redirect_to places_url, notice: 'Place was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_place
#place = Place.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def place_params
params.require(:place).permit(:name, :address, :description, :phone, :website)
end
end
/pages/dashboard.html.erb
<div class="container">
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-5">
<h3>My Places</h3>
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Created</th>
<th></th>
</tr>
</thead>
<tbody>
<% #places.each do |place| %>
<tr>
<td><%= place.name %></td>
<td><%= time_ago_in_words(place.created_at) %> ago</td>
<td><%= link_to "Edit", edit_place_path(place) %>|<%= link_to "Destroy", place_path(place), method: :delete %></td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to "New Place", new_place_path %>
</div>
<h3>My Reviews</h3>
<table class="table table-hover">
<thead>
<tr>
<th>Place</th>
<th>Created</th>
<th></th>
</tr>
</thead>
<tbody>
<% #reviews.each do |review| %>
<tr>
<td><%= review.place.name %></td>
<td><%= time_ago_in_words(review.created_at) %> ago</td>
<td><%= link_to "Edit", edit_review_path(review) %>|<%= link_to "Destroy", review_path(review), method: :delete %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
Here's a screenshot :
Did anyone had this issue before ?
the problem that you are having is that the place is nil.
you can add a a try method like this
<td><%= review.place.try(:name) %></td>
The review has no associated places. So, You should implement a check before attempting to render it.
Try this:
<td><%= review.try(:place).try(:name) %></td>

Resources