I'm new to Stackoverflow & rails, but hello!
I've had a look around and can't quite get everything together.
I'm creating a dashboard that will allow a user to add a new client with 4 different fields. Then allowing the user to add projects, with 8 different fields to a particular client. However, I'm struggling to add a project to a client and get it to show up. I've made my code public at: https://github.com/JackStovell/revenue-dashboard.
Please rip my code to pieces & tell me where I'm going wrong so I can adjust it!
Thanks
Here's some snippets:
Project Model:
class Project < ActiveRecord::Base
belongs_to :client
end
Client model
class Client < ActiveRecord::Base
has_many :projects
end
Projects Controller
class ProjectsController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :set_project, only: [:show, :edit, :update, :destroy]
# GET /projects
# GET /projects.json
def index
#projects = Project.all
#clientnav = Client.all
end
# GET /projects/1
# GET /projects/1.json
def show
#project = Project.find(params[:id])
#clientnav = Client.all
end
# GET /projects/new
def new
#project = Project.new
#client = Client.all
#clientnav = Client.all
end
# GET /projects/1/edit
def edit
#clientnav = Client.all
#client = Client.all
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(project_params)
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
#clientnav = Client.all
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
#clientnav = Client.all
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
format.json { head :no_content }
end
#clientnav = Client.all
end
def income
#project.income = params[#project.billing] - params[#project.cost]
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:id, :name, :jobNumber, :status, :billing, :cost, :income)
end
end
Clients Controller
class ClientsController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :set_client, only: [:show, :edit, :update, :destroy]
# GET /clients
# GET /clients.json
def index
#clients = Client.all
#clientnav = Client.all
end
# GET /clients/1
# GET /clients/1.json
def show
#client = Client.find(params[:id])
#projects = #client.projects
#clientnav = Client.all
end
# GET /clients/new
def new
#client = Client.new
#clientnav = Client.all
end
# GET /clients/1/edit
def edit
#clientnav = Client.all
end
# POST /clients
# POST /clients.json
def create
#clientnav = Client.all
#client = Client.new(client_params)
respond_to do |format|
if #client.save
format.html { redirect_to #client, notice: 'Client was successfully created.' }
format.json { render :show, status: :created, location: #client }
else
format.html { render :new }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
respond_to do |format|
if #client.update(client_params)
format.html { redirect_to #client, notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: #client }
else
format.html { render :edit }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
#clientnav = Client.all
end
# DELETE /clients/1
# DELETE /clients/1.json
def destroy
#client.destroy
respond_to do |format|
format.html { redirect_to clients_url, notice: 'Client was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
#client = Client.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def client_params
params.require(:client).permit(:clientName, :clientOwner, :analysis, :analysis2)
end
end
Code:
clients_controller.rb
def new
#client = Client.new
#project = #client.projects.build
end
def create
#client = Client.new(client_params)
#client.save
end
def client_params
params.require(:client).permit(:id, :client_name, ...,
project_attributes: [:name, ...] )
end
projects/_form.html.erb
<%= f.label :clientName %>
<%= f.text_field :clientName"%>
....
....
<%= f.fields_for :projects do |project| %>
<%= project.label :name %>
<%= project.text_field :name%>
....
....
<%end%>
model/client.rb
accepts_nested_attributes_for :projects
Related
I'm working on a project, and for the life of me, I'm not sure what's going on. My code was working earlier, now I'm getting
NoMethodError in MoviesController#upvote
When I try and vote on a certain movie, here is my "movie_controller.rb"
class MoviesController < ApplicationController
before_action :set_movie, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
before_action :authenticate_user!
# GET /movies
# GET /movies.json
def index
#movies = Movie.all
end
# GET /movies/1
# GET /movies/1.json
def show
end
# GET /movies/new
def new
#movie = Movie.new
end
# GET /movies/1/edit
def edit
end
# POST /movies
# POST /movies.json
def create
#movie = Movie.new(movie_params)
respond_to do |format|
if #movie.save
format.html { redirect_to #movie, notice: 'Movie was successfully created.' }
format.json { render :show, status: :created, location: #movie }
else
format.html { render :new }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /movies/1
# PATCH/PUT /movies/1.json
def update
respond_to do |format|
if #movie.update(movie_params)
format.html { redirect_to #movie, notice: 'Movie was successfully updated.' }
format.json { render :show, status: :ok, location: #movie }
else
format.html { render :edit }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# DELETE /movies/1
# DELETE /movies/1.json
def destroy
#movie.destroy
respond_to do |format|
format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
format.json { head :no_content }
end
end
def upvote
#movie.upvote_from current_user
redirect_to movies_path
end
def downvote
#movie.downvote_from current_user
redirect_to movies_path
end
private
def set_movie
#movies = Movie.find(params[:movie_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def movie_params
params.require(:movie).permit(:title, :image)
end
end
In particular it's saying there's a problem with is line:
private
def set_movie
#movies = Movie.find(params[:id])
end
I'll also attach my routes for good measure. Thank you guys.
Rails.application.routes.draw do
devise_for :users
root 'home#index'
resources :movies do
put "like", to: "movies#upvote"
put "unlike", to: "movies#downvote"
end
end
The problem is that you are setting a #movies variable instead of #movie. That's why you are getting a undefined method upvote_from' for nil:NilClass def upvote #movie.upvote_from
Change this part of the code
private
def set_movie
#movies = Movie.find(params[:id])
end
to this
private
def set_movie
#movie = Movie.find(params[:id])
end
My issue is, when I am under the camper show page
Current Camper URL:
campers/1
and I go to click on to view the appointment it uses the camper_id for the appointment_id which is wrong so say if the camper_id is 1 it will use the appointment_id as 1 and actually the appointment id is 3, so then it says Couldn't find appointment with id of 1.
Table Header
<% #appointments.each do |app| %>
<%= link_to app.camper.camperName, appointment_path(#camper, #appointment) %>
Campers Controller Show Action
#appointments = #camper.appointments
Camper Model
has_many :appointments, dependent: :destroy
Appointment Model
belongs_to :camper
Shallow Nested Routes File
resources :customers, shallow: :true do
resources :campers do
resources :appointments do
resources :orders do
member do
patch :complete
end
end
end
end
end
Camper Controller
class CampersController < ApplicationController
before_action :set_camper, only: [:show, :edit, :update, :destroy]
# before_action :set_customer, only: [:index, :new, :edit, :create, :update]
load_and_authorize_resource
# GET /campers
# GET /campers.json
def index
#campers = #customer.campers
end
def list
query = params[:q].presence || ""
#campers = Camper.search(query, page: params[:page], per_page: 20, order: {created_at: :desc} )
end
# GET /campers/1
# GET /campers/1.js
def show
#appointments = #camper.appointments
respond_to do |format|
format.html
format.json
end
end
# GET /campers/new
def new
#customer = Customer.find(params[:customer_id])
#camper = #customer.campers.build
end
# GET /campers/1/edit
def edit
end
def page_name
"Campers"
end
# POST /campers
# POST /campers.json
def create
#camper = Camper.new(camper_params)
respond_to do |format|
if #camper.save
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully created.' }
format.json { render :show, status: :created, location: #camper }
else
format.html { render :new }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /campers/1
# PATCH/PUT /campers/1.json
def update
respond_to do |format|
if #camper.update(camper_params)
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully updated.' }
format.json { render :show, status: :ok, location: #camper }
else
format.html { render :edit }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# DELETE /campers/1
# DELETE /campers/1.json
def destroy
#camper.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'Camper was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_camper
#camper = Camper.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def camper_params
params.require(:camper).permit(:order_id, :customer_id, :year, :manufacturer, :modelName, :camperClass, :vin, :mileage, :notes, :user_id)
end
end
Appointments Controller
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
# GET /appointments
# GET /appointments.json
def index
#camper = Camper.find(params[:camper_id])
#appointments = #camper.appointments
end
# GET /appointments/1
# GET /appointments/1.json
def show
#orders = #appointment.orders
end
# GET /appointments/newå
def new
#camper = Camper.find(params[:camper_id])
#appointment = #camper.appointments.build
end
# GET /appointments/1/edit
def edit
end
# POST /appointments
# POST /appointments.json
def create
#appointment = Appointment.new(appointment_params)
respond_to do |format|
if #appointment.save
format.html { redirect_to appointment_path(#appointment), notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1
# PATCH/PUT /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /appointments/1
# DELETE /appointments/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to camper_appointments_path(#appointment), notice: 'Appointment was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:customer_id, :camper_id, :order_id, :title, :description, :date_in, :date_out)
end
end
appointment_path only takes a single appointment argument. Remove the #camper argument:
appointment_path(#appointment)
I checked the other simple_form posts and they didn't quite hit on my problem. I have a nested resource for restaurant reviews in my routes.rb here:
Rails.application.routes.draw do
devise_for :users
resources :restaurants do
resources :reviews, except: [:show, :index]
end
My review controller seems to be set properly here:
class ReviewsController < ApplicationController
before_action :authenticate_user!
before_action :set_restaurant
before_action :set_review, only: [:edit, :update, :destroy]
# 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.restaurant_id = #restaurant.id
respond_to do |format|
if #review.save
format.html { redirect_to root_path, notice: 'Review was successfully created.' }
format.json { render :show, status: :created, location: #review }
else
format.html { render :new }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
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_restaurant
#restuarant = Restaurant.find(params[:restaurant_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:rating, :comment)
end
end
My restaurant controller is here:
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:show, :edit, :update, :destroy]
# GET /restaurants
# GET /restaurants.json
def index
#restaurants = Restaurant.all
end
# GET /restaurants/1
# GET /restaurants/1.json
def show
end
# GET /restaurants/new
def new
#restaurant = Restaurant.new
end
# GET /restaurants/1/edit
def edit
end
# POST /restaurants
# POST /restaurants.json
def create
#restaurant = Restaurant.new(restaurant_params)
respond_to do |format|
if #restaurant.save
format.html { redirect_to #restaurant, notice: 'Restaurant was successfully created.' }
format.json { render :show, status: :created, location: #restaurant }
else
format.html { render :new }
format.json { render json: #restaurant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /restaurants/1
# PATCH/PUT /restaurants/1.json
def update
respond_to do |format|
if #restaurant.update(restaurant_params)
format.html { redirect_to #restaurant, notice: 'Restaurant was successfully updated.' }
format.json { render :show, status: :ok, location: #restaurant }
else
format.html { render :edit }
format.json { render json: #restaurant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /restaurants/1
# DELETE /restaurants/1.json
def destroy
#restaurant.destroy
respond_to do |format|
format.html { redirect_to restaurants_url, notice: 'Restaurant was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_restaurant
#restaurant = Restaurant.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :address, :phone, :website, :image)
end
end
and my simple_form_for is super straight forward:
<%= simple_form_for [#restaurant, #review] do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :rating %>
<%= f.input :comment %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
So, I don't know why I am getting this error :(
You need to provide the value of #restaurant which since you mispelled it as #restuarant will not work.
My application consists of Items. They have a status attribute that's a boolean. I added it to items by doing rails g migration AddStatusToItems status:boolean. To show the status of an item as either complete or pending, in the view, I just do
<% if status? %>
Complete
<% else %>
Pending
<% end %>
Oh yeah, I also added :status to the params hash in the controller.
It works as it should locally, but on Heroku the status just goes back to pending. Here's the log on Heroku. How can I get this working?
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show, :upvote]
# GET /items
# GET /items.json
def index
#items = Item.all.order('created_at DESC')
end
# GET /items/1
# GET /items/1.json
def show
end
# GET /items/new
def new
#item = Item.new
end
# GET /items/1/edit
def edit
end
# POST /items
# POST /items.json
def create
#item = current_user.items.new(item_params)
respond_to do |format|
if #item.save
format.html { redirect_to root_path, notice: 'Item was successfully created.' }
format.json { render action: 'show', status: :created, location: #item }
else
format.html { render action: 'new' }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
respond_to do |format|
if #item.update(item_params)
format.html { redirect_to #item, notice: 'Item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item.destroy
respond_to do |format|
format.html { redirect_to items_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
#item = Item.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:name, :quantity, :boughtfor, :soldfor, :user_id, :status)
end
end
I have a Listings Controller where Users can Create their Listings.
To prevent users to edit other users listings i just had to update every action from
Listing to current_user.listings
but with Rails 4 the controller got changed and i can't find how to set this up.
My Controller File->
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :only => [:index]
# GET /listings
# GET /listings.json
def index
#listings = Listing.all
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
#listing = Listing.new
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(listing_params)
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render action: 'show', status: :created, location: #listing }
else
format.html { render action: 'new' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if #listing.update(listing_params)
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:title, :description)
end
end
Anyone knows a Solution ?
change from #new to build. So, change all #listing = Listing.new to:
#listing = current_user.listings.build
Then, in set_listing change to:
#listing = current_user.listings.find(params[:id])