I'm creating a website using Ruby on Rails. I met a problem which i need to display my data as text on my web page for example <h2><%=#permits.permitstart%></h2>but i keep getting this error
NoMethodError in Permits#show
Showing C:/Users/GaryVLC/RubymineProjects/Parking_and_Safety_3/app/views/permits/show.html.erb where line #7 raised:
undefined method `permitstart' for #<Permit::ActiveRecord_Relation:0xb69e290>
I'm not sure whether I'm inputing the correct stuff in my controller. Can you guys please have a look? Any help is appreciated!
This is the web page I want my data be render (show.html.erb)
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2><%=#permits.permitstart%></h2></br>
</div>
</div>
This is the web page that the button clink into the (show.html.erb)
<h2>My Permits</h2>
<table>
<tr>
<th>Permit Start Date</th>
<th>Permit End Data</th>
<th>Action</th>
<th> </th>
</tr>
<% #permits.each do |permit| %>
<tr>
<td><%= permit.permitstart %></td>
<td><%= permit.permitend %></td>
<td><%= link_to 'Detail', viewpermit_path(permit) %></td>
<td><%= link_to 'Edit', edit_permit_path(permit) %></td>
</tr>
<% end %>
</table>
This is my permits controller
class PermitsController < ApplicationController
before_action :set_permit, only: [:destroy]
def index
#permits = Permit.where(:user_id => current_user.id)
end
def new
#permits = Permit.new
end
def create
#permits = current_user.permits.build(permit_params)
if #permits.save
redirect_to invoice_path
else
render 'new'
end
end
def destroy
Permit.destroy_all(user_id: current_user)
respond_to do |format|
format.html { redirect_to root_path, notice: 'Permit was successfully canceled.' }
format.json { head :no_content }
end
end
def confirm
#fields = %i[vehicle_type, carplate, studentid, name, department, permitstart, permitend]
#permit = current_user.permits.build(permit_params)
render :new and return unless #permit.valid?
end
def show
#permits = Permit.where(:user_id => current_user.id)
end
def update
#permits = Permit.where(user_id: current_user).take
respond_to do |format|
if #permits.update(permit_params)
format.html { redirect_to root_path}
flash[:success] = "Permit successfully updated"
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def edit
#permits = Permit.find(params[:id])
##permits = Permit.find_or_initialize_by(user_id: params[:id])
end
def detail
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
#permits = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration, :permitstart, :permitend)
end
end
This is my route.db
Rails.application.routes.draw do
resources :users
resources :permits do
collection do
post :confirm
end
end
resources :visitor_permits
root 'static_pages#home'
get 'viewpermit' =>'permits#show'
get 'invoice' => 'permits#invoice'
get 'payment' =>'transaction#new'
get 'show_visitor_permit' =>'visitor_permits#show'
get 'show_permit' =>'permits#index'
get 'visitorpermit' => 'visitor_permits#new'
post 'createpermit' => 'permits#create'
get 'homepage/index'
post 'permits' => 'permits#create'
get 'permitapplication' => 'permits#new'
get 'adminlogin' => 'admin_controller#index'
get 'patrollogin' => 'patrol_officer_controller#index'
get 'createcitation' => 'citations#new'
get 'contact'=> 'static_pages#contact'
get 'about' => 'static_pages#about'
get 'signup' => 'users#new'
get 'help' => 'static_pages#help'
post 'users' =>
'users#create'
get 'login' => 'sessions#new' #Page for a new session
post 'login' => 'sessions#create' #Create a new session
delete 'logout'=>'sessions#destroy' #Delete a session
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
You're calling an instance method on a collection object (the method doesn't exist).
You'll need to loop through the #permits object and call permitstart on each model object it contains:
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<% #permits.each do |p| %>
<h2><%= p.permitstart %></h2></br>
<% end %>
</div>
</div>
--
Alternatively, if you're seeing this error in the show action, you need to use the following:
def show
#permits = current_user.permits.find(params[:id])
end
Because this method
def show
#permits = Permit.where(:user_id => current_user.id)
end
Gives you a relation (an ActiveRecord_Relation), not a single Permit object. You could take the first one but I don't know if it's what you want. Anyway, this is the issue.
#permits = Permit.where(:user_id => current_user.id).first
Related
I've been trying to build a facebook/blog type app where comments show directly under new posts, and you can also POST a new comment by rendering a form directly under the corresponding Post. As you'll learn in the rest of my post, I'm fairly new to Rails so any resources that directly help me understand the issue I'm having (even if it's just pointing me to the right parts of the Rails docs) would be super helpful.
As of right now, my homepage renders the post#index action, as well as a a post form so that you can create new posts directly on the index page. All of this works fine until I try to render my comment form. As a note, I'm only focusing on creating a new comment before implementing editing and deleting (not that that should affect anything I wouldn't think).
Unfortunately I keep getting this error -
Moreover, when I split each of these pages into a more traditional, link_to XXXX_path style where every form and action is on its own url page, everything works fine. I think there might be something fundamental that I'm just not understanding. So, before showing my code I'll just give a quick explanation of my understanding of how I expect things to work in my app
On the index.html.erb view:
Render the index page
Show each individual post and any corresponding info I want to display with my each method.
pass the specific instance of Post using <%= render 'comment_form', :post => post %>. This should also give me access to all of the params of said instance of post in my _comment_form.html.erb partial.
On the _comment_form.html.erb partial:
add model: [post, #comment] (as my comment controller is nested in post) so that Rails knows to build a new comment with the associated post instance that was pushed through my index view.
At the end of the day, if I had to guess, my issue is with my controllers - I feel like I've put the correct code in the methods/actions, but my hunch is that there's something conflicting between the #post instance variable and the post instance being iterated over in my each method. I'm really not sure what the problem is and any help would be much appreciated. I hope I didn't over (or under) explain my problem. Thanks for the help in advance!
views/posts/index.html.erb
<p id="notice"><%= notice %></p>
<nav>
</nav>
<h1>Posts</h1>
<table>
<thead>
<tr>
<th>User</th>
<th>Body</th>
<th colspan="3"></th>
</tr>
</thead>
<%= render 'form' %>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= link_to post.user.email, user_path(post.user_id) %></td>
<td><%= post.body %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<td>
</tr>
<tr>
<%= render 'comment_form', :post => post %>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_post_path %>
views/posts/_comment_form.html.erb
<% if user_signed_in? %>
<%= form_with(model: [post, #comment], url: post_comments_path, method: "post", local: true) do |form| %>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
<% else %>
Please sign in to comment on the post!
<% end %>
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
#before_action :authenticate_user!
# GET /posts
# GET /posts.json
def index
#posts = Post.all.order("created_at DESC")
#post = post_exists?
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = current_user.posts.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.build(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to index, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:body)
end
def post_exists?
current_user.posts.build if current_user != nil
end
end
comments_controller.rb
class CommentsController < ApplicationController
def new
#post = Post.find(params[:post_id])
#comment = #post.comments.build
end
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(comments_params)
#comment.user_id = current_user.id
respond_to do |format|
if #comment.save
format.html { redirect_to posts_path, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
end
private
def comments_params
params.require(:comment).permit(:body)
end
end
routes.rb
devise_for :users, controllers: {
sessions: 'users/sessions'
}
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
resources :posts do
resources :comments, only: [:new, :create, :destroy]
end
resources :users
root to: 'posts#index'
Models
>user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
>post.rb
belongs_to :user
has_many :comments, dependent: :destroy
>comment.rb
belongs_to :user
belongs_to :post
The error is saying that it is missing the post_id on line 2 in your comment_form.
You got:
<%= form_with(model: [post, #comment], url: post_comments_path, method: "post", local: true) do |form| %>
The url is set to post_comments_path but it doesn't knows which post so you need to pass the post to it as an argument like so:
<%= form_with(model: [post, #comment], url: post_comments_path(post), method: "post", local: true) do |form| %>
Although this will probably solve the current error, you will hit another error since you also got #comment in the comment_form and in your posts#index you don't declare #comment. You also can't declare #comment because it is depending on the post. You could try to solve that with:
<%= form_with(model: [post, post.comments.new], url: post_comments_path, method: "post", local: true) do |form| %>
I've been stuck on this all day. When I try to show the details of a job, create a job, or edit a current job in my ruby on rails project I get a NoMethodError in Jobs#show on the second last line explaining there is a problem with the link to the edit page.
Jobs/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #job.name %>
</p>
<p>
<strong>Employer:</strong>
<%= #job.employer %>
</p>
<p>
<strong>Sector:</strong>
<%= #job.sector_id %>
</p>
<p>
<strong>Experience req:</strong>
<%= #job.experience_req %>
</p>
<p>
<strong>Job info:</strong>
<%= #job.job_info %>
</p>
<h2>Star comment: </h2>
<%=form_for([#job, Request.new]) do |f| %>
</h3></br>
<%= f.text_area:content, :rows => 4, :cols=> 40%>
<div class = "actions">
<%=f.submit "Make a request for the job"%>
</div>
<% end %>
<%if #job.requests.empty? %>
<h3> You are the first to Request</h3>
<% else %>
<h2> Who else had made a request for this job:</h2>
<% #job.requests.reverse.each do |request| %>
<p><%= request.content %>
Posted <%=time_ago_in_words(request.created_at)%> ago by
<%=request.candidate.can_name%></p>
<% end %>
<% end %>
<%= link_to 'Edit', edit_jobs_path(#job) %> | **This line highlights an error**
<%= link_to 'Back', jobs_path %>
Jobs/edit.html
<h1>Editing job</h1>
<%= render 'form' %>
<%= link_to 'Show', #job %> |
<%= link_to 'Back', jobs_path %>
Routes
Rails.application.routes.draw do
# get 'sessions/new'
# get 'sessions/create'
#get 'sessions/destroy'
controller :sessions do
get 'login' =>:new
post 'login' =>:create
get 'logout' =>:destroy
delete 'logout' =>:destroy
end
#get 'pages/home'
#get 'pages/about'
resources :candidates
resources :requests
resources :employers
resources :jobs
resources :sectors
# The priority is based upon order of creation: first created -> highest
# priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'pages#home'
#root :to=>'pages#home
#'welcome#index'
resources :jobs do
resources :requests
end
end
Jobs_Controller
class JobsController < ApplicationController
before_action :set_job, only: [:show, :edit, :update, :destroy]
# GET /jobs
# GET /jobs.json
def index
#jobs = Job.all
end
# GET /jobs/1
# GET /jobs/1.json
def show
end
# GET /jobs/new
def new
#job = Job.new
end
# GET /jobs/1/edit
def edit
end
# POST /jobs
# POST /jobs.json
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.'
}
format.json { render :show, status: :created, location: #job }
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity
}
end
end
end
# PATCH/PUT /jobs/1
# PATCH/PUT /jobs/1.json
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.'
}
format.json { render :show, status: :ok, location: #job }
else
format.html { render :edit }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jobs/1
# DELETE /jobs/1.json
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url, notice: 'Job was successfully
destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white
#list through.
def job_params
params.require(:job).permit(:name, :employer, :sector_id,
:experience_req,:job_info)
end
end
Update
Ursus informed me I had to change <%= link_to 'Show', #job %> to<%= link_to 'Show', job_path(#job) %> in Jobs/edit.html. I did this, however when I try to create a new job or edit a current job I still get the same error but the new job is still created?
This
<%= link_to 'Show', #job %>
should be
<%= link_to 'Show', job_path(#job) %>
Hi guys I keep get this error when i try to access to render out one specific permit data from the permits model to the detail.html.erb, i search through all my code and couldn't find the bug. Can you guys help me to check which part i did wrong? Btw I'm implementing a website using Ruby on rails
This is my permits_controller.rb
class PermitsController < ApplicationController
before_action :set_permit, only: [:destroy]
def index
#permits = Permit.where(:user_id => current_user.id)
end
def new
#permits = Permit.new
end
def create
#permits = current_user.permits.build(permit_params)
if #permits.save
redirect_to invoice_path
else
render 'new'
end
end
def destroy
Permit.destroy_all(user_id: current_user)
respond_to do |format|
format.html { redirect_to root_path, notice: 'Permit was successfully canceled.' }
format.json { head :no_content }
end
end
def confirm
#fields = %i[vehicle_type, carplate, studentid, name, department, permitstart, permitend]
#permit = current_user.permits.build(permit_params)
render :new and return unless #permit.valid?
end
def show
#permits = Permit.where(:user_id => current_user.id)
end
def update
#permits = Permit.where(user_id: current_user).take
respond_to do |format|
if #permits.update(permit_params)
format.html { redirect_to root_path}
flash[:success] = "Permit successfully updated"
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def edit
#permits = Permit.find(params[:id])
##permits = Permit.find_or_initialize_by(user_id: params[:id])
end
def detail
#permits = Permit.find(params[:id])
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
#permits = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration, :permitstart, :permitend)
end
end
Detail.html.erb
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2><%= #permits.permitstart %></h2>
</div>
</div>
Route.db
Rails.application.routes.draw do
resources :users
resources :permits do
collection do
post :confirm
end
end
resources :visitor_permits
root 'static_pages#home'
get 'viewpermit' =>'permits#detail'
get 'invoice' => 'permits#invoice'
get 'payment' =>'transaction#new'
get 'show_visitor_permit' =>'visitor_permits#show'
get 'show_permit' =>'permits#show'
get 'visitorpermit' => 'visitor_permits#new'
post 'createpermit' => 'permits#create'
get 'homepage/index'
post 'permits' => 'permits#create'
get 'permitapplication' => 'permits#new'
get 'adminlogin' => 'admin_controller#index'
get 'patrollogin' => 'patrol_officer_controller#index'
get 'createcitation' => 'citations#new'
get 'contact'=> 'static_pages#contact'
get 'about' => 'static_pages#about'
get 'signup' => 'users#new'
get 'help' => 'static_pages#help'
post 'users' => 'users#create'
get 'login' => 'sessions#new' #Page for a new session
post 'login' => 'sessions#create' #Create a new session
delete 'logout'=>'sessions#destroy' #Delete a session
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
This is my linking page (show.html.erb)
<h2>My Permits</h2>
<table>
<tr>
<th>Permit Start Date</th>
<th>Permit End Data</th>
<th>Action</th>
<th> </th>
</tr>
<% #permits.each do |permit| %>
<tr>
<td><%= permit.permitstart %></td>
<td><%= permit.permitend %></td>
<td><%= link_to 'Detail', viewpermit_path(permit) %></td>
<td><%= link_to 'Edit', edit_permit_path(permit) %></td>
</tr>
<% end %>
</table>
You haven't defined your routes in a proper way. Your routes simply redirects to action #detail but you don't set your variables within the route. You have multiple options
resources :permits do
collection do
post :confirm
end
member do
get 'viewpermit' # enables a route like /permits/1/viewpermit
end
end
# or
get 'viewpermit/:id' => 'permits#detail' #enables route /viewpermit/1
EDIT:
In your show action.replace where to find
def show
#permits = Permit.find(params[:id])
end
I have a parent/children relationship model with nested resources setup in order to create child data under a certain parent from it's show page. However, when I click on the child's new page link from the parent page ("http://localhost:3000/brands/1/restaurants/new"), I get an error saying that "NoMethodError in...". Please help.
config/routes.rb
Rails.application.routes.draw do
resources :brands, shallow: true do
resources :restaurants
end
resources :managers
# Prefix Verb URI Pattern Controller#Action
# brand_restaurants GET /brands/:brand_id/restaurants(.:format) restaurants#index
# POST /brands/:brand_id/restaurants(.:format) restaurants#create
# new_brand_restaurant GET /brands/:brand_id/restaurants/new(.:format) restaurants#new
# edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
# restaurant GET /restaurants/:id(.:format) restaurants#show
# PATCH /restaurants/:id(.:format) restaurants#update
# PUT /restaurants/:id(.:format) restaurants#update
# DELETE /restaurants/:id(.:format) restaurants#destroy
# brands GET /brands(.:format) brands#index
# POST /brands(.:format) brands#create
# new_brand GET /brands/new(.:format) brands#new
# edit_brand GET /brands/:id/edit(.:format) brands#edit
# brand GET /brands/:id(.:format) brands#show
# PATCH /brands/:id(.:format) brands#update
# PUT /brands/:id(.:format) brands#update
# DELETE /brands/:id(.:format) brands#destroy
# managers GET /managers(.:format) managers#index
# POST /managers(.:format) managers#create
# new_manager GET /managers/new(.:format) managers#new
# edit_manager GET /managers/:id/edit(.:format) managers#edit
# manager GET /managers/:id(.:format) managers#show
# PATCH /managers/:id(.:format) managers#update
# PUT /managers/:id(.:format) managers#update
# DELETE /managers/:id(.:format) managers#destroy managers#destroy
end
models/brand.rb
class Brand < ActiveRecord::Base
has_many :restaurants
end
models/restaurants.rb
class Restaurant < ActiveRecord::Base
belongs_to :brand
end
controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:new, :create, :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
#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 brands_path, 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_by(params[:brand_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :brand_id) if params[:restaurant]
end
end
views/brands/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #brand.name %>
</p>
<p>
<strong>Manager:</strong>
<%= #brand.manager_id %>
</p>
<table>
<% #brand.restaurants.each do |restaurant| %>
<tr>
<td><%= restaurant.name %></td>
<td><%= restaurant.brand_id %></td>
<td><%= link_to 'Show', restaurant %></td>
<td><%= link_to 'Edit', edit_restaurant_path(restaurant) %></td>
<td><%= link_to 'Destroy', restaurant, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br>
**<%= link_to 'Add New Restaurant', new_brand_restaurant_path(#brand) %>**
<%= link_to 'Edit', edit_brand_path(#brand) %> |
<%= link_to 'Back', brands_path %>
What did I do wrong?
Appreciate your help.
Addin Full Error Message:
NoMethodError in Restaurants#new Showing
/Users/kaku/sample/relation/app/views/restaurants/_form.html.erb where
line #1 raised:
undefined method `restaurants_path' for
<#:0x007fd4ec2e46e0> Extracted source (around line #1): 1 2 3 4 5 6
<%= form_for(#restaurant) do |f| %>
<% if #restaurant.errors.any? %>
<%= pluralize(#restaurant.errors.count, "error") %> prohibited this restaurant from being saved:
Trace of template inclusion: app/views/restaurants/new.html.erb
Rails.root: /Users/kaku/sample/relation
Application Trace | Framework Trace | Full Trace
app/views/restaurants/_form.html.erb:1:in
_app_views_restaurants__form_html_erb__1732550980462972679_70276222510780' app/views/restaurants/new.html.erb:3:in
_app_views_restaurants_new_html_erb___209183791776779444_70276222559000'
Request
Parameters:
{"brand_id"=>"2"} Toggle session dump
_csrf_token: "MG3xNH+mscxxPiQqLVkF011BDb5RGlWJPuTN3GiEcGo=" session_id: "e1f92f37d231a058162af62bae976ff5" Toggle env dump
GATEWAY_INTERFACE: "CGI/1.1" HTTP_ACCEPT:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8"
HTTP_ACCEPT_ENCODING: "gzip, deflate, sdch" HTTP_ACCEPT_LANGUAGE:
"ja,en-US;q=0.8,en;q=0.6" REMOTE_ADDR: "::1" REMOTE_HOST: "::1"
SERVER_NAME: "localhost" SERVER_PROTOCOL: "HTTP/1.1" Response
Headers:
None
As you pointed in the code, I believe the error is in this line
<%= link_to 'Add New Restaurant', new_brand_restaurant_path(#brand) %>
You should have #brand in the new method of restaurants_controller
def new
#brand = Brand.find(params[:brand_id])
#restaurant = Restaurant.new
end
And also I noticed that you have defined set_restaurant wrongly. It should be
def set_restaurant
#restaurant = Restaurant.find(params[:id])
end
Update:
undefined method `restaurants_path'
You have nested resources, so this line
<%= form_for(#restaurant) do |f| %>
should be
<%= form_for [#brand, #restaurant] do |f| %>
In my Ruby on Rails application users are able to leave reviews for products, and then the administrator can view all reviews. What I want to be able to do is make it so that an administrator can still see all reviews left by everyone but a normal user can only view their own reviews and not everyone elses. Is there a simple way I can do this without using java?
Below is my index.html.erb that displays all reviews by everyone.
<div class="centre-content">
<div class="main-title">All reviews:</div>
<table>
<tr>
<th>Product</th>
<th>Name</th>
<th>Review text</th>
<th>No of stars</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #reviews.each do |review| %>
<tr>
<td><%= review.product.title %></td>
<td><%= review.user.name %></td>
<td><%= review.review_text.truncate(35) %></td>
<td><%= review.no_of_stars %></td>
<td><%= link_to 'Show', review %></td>
<td><%= link_to 'Edit', edit_review_path(review) %></td>
<td><%= link_to 'Destroy', review, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'Back', :back %>
</div>
application.html.erb where the administrator can click to view all reviews:
<% if admin? %>
<li> <%= link_to "Users", "" , :class => active_menu("users") %>
<ul>
<li> <%= link_to "Users" , users_path %> </li>
<li> <%= link_to "Edit profile" , edit_user_path(session[:user_id]) %> </li>
</ul>
<li> <%= link_to "Categories", categories_path , :class => active_menu("categories") %>
<li> <%= link_to "Reviews", reviews_path , :class => active_menu("reviews") %>
<% end %>
reviews_controller.rb:
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
# GET /reviews
# GET /reviews.json
def index
#reviews = Review.all
end
# GET /reviews/1
# GET /reviews/1.json
def show
end
def new
if logged_in?
existing_review = Review.find_by_user_id_and_product_id(session[:user_id], params[:id])
if existing_review == nil
#review = Review.new(product_id: params[:id],
user_id: User.find(session[:user_id]).id)
session[:return_to] = nil
else
redirect_to edit_review_path(existing_review.id)
end
else
session[:return_to] = request.url
redirect_to login_path, alert: "You need to login to write a review"
end
end
# GET /reviews/1/edit
def edit
end
def create
#review = Review.new(review_params)
if #review.save
product = Product.find(#review.product.id)
redirect_to product, notice: 'Your review was successfully added.'
else
render action: 'new'
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 { head :no_content }
else
format.html { render action: '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 }
format.json { head :no_content }
end
end
def displays
product = Product.find(params[:id])
#reviews = product.reviews
if #reviews.empty?
redirect_to product, notice: "No reviews - as yet ..."
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:product_id, :user_id, :review_text, :no_of_stars)
end
end
reviews.rb model:
class Review < ActiveRecord::Base
belongs_to :product
belongs_to :user
validates :review_text, :presence => { :message => "Review text: cannot be blank ..."}
validates :review_text, :length => {:maximum => 2000, :message => "Review text: maximum length 2000 characters"}
validates :no_of_stars, :presence => { :message => "Stars: please rate this book ..."}
end
Is there anyway I can make it so that a user only views their own reviews?
In your controller display method, you can do stg like this i think :
def display
product = Product.find(params[:id])
#reviews = product.reviews.select! { |s| s.user_id == current_user.id } unless admin?
....
end
That way, only admin will have all reviews, and others users will only see their own reviews (with theirs ids)
you dont have current_user method but it es explained well in this tutorial :
https://www.railstutorial.org/book/log_in_log_out#sec-current_user
it is the same as session[:id] but in a well ordered manner.
Ps: i'm not sur about the s.user_id ... don't remember the exact syntax but should be it.
Another way :
you could take the reviews for this specific product id and then filter out by the user id.
`#reviews = Reviews.find_by_product_id(params[:product_id]).select { |r| r.user_id == current_user.id }`