ActiveRecord::RecordNotFound in EmployeesController#edit - ruby-on-rails

I am getting an error when trying to edit an employee. The full error message is:
ActiveRecord::RecordNotFound in EmployeesController#edit
Couldn't find Company with 'id'=5 (*this varies depending on which company I click on)
Extracted source (around line #57):
def find_company
#company = Company.find(permitted_params[:company_id])
end
end
With this application I have companies and employees. I can add, show and delete employees within the companies but I am unable to edit them due to this error. I am new to Rails and am unsure where I have gone wrong.
routes.rb:
Rails.application.routes.draw do
get 'welcome/index'
resources :companies do
resources :employees
end
root 'welcome#index'
get 'companies/new'
end
Employees controller:
class EmployeesController < ApplicationController
before_action :find_company
before_action :set_employee, only: %i[show edit update destroy]
def index
#employees = #company.employees
end
def show
#employee = Employee.find(params[:id])
end
def new
#employee = #company.employees.build
end
def edit
#employee = Employee.find(params[:id])
end
def create
#employee = #company.employees.build(permitted_params[:employee])
if #employee.save
redirect_to company_employees_path(#company)
else
render 'new'
end
end
def update
if #employee.update(forename: permitted_params[:forename],
surname: permitted_params[:surname])
redirect_to company_employees_path(#company)
else
render 'edit'
end
end
def destroy
#employee.destroy
redirect_to company_employees_path(#company)
end
private
def set_employee
#employee = Employee.find(permitted_params[:id])
end
def permitted_params
params.permit!
end
def find_company
#company = Company.find(permitted_params[:company_id])
end
end
Companies controller:
class CompaniesController < ApplicationController
def index
#company = Company.all
end
def show
#company = Company.find(permitted_params[:id])
# #company = Company.first
end
def new
#company = Company.new
end
def create
#company = Company.new(permitted_params[:company])
if #company.save
redirect_to #company
else
render 'new'
end
end
def destroy
#company = Company.find(permitted_params[:id])
#company.destroy
redirect_to companies_path
end
private
def permitted_params
params.permit!
end
end
Rake routes output:
Prefix Verb URI Pattern Controller#Action
welcome_index GET /welcome/index(.:format) welcome#index
company_employees GET /companies/:company_id/employees(.:format) employees#index
POST /companies/:company_id/employees(.:format) employees#create
new_company_employee GET /companies/:company_id/employees/new(.:format) employees#new
edit_company_employee GET /companies/:company_id/employees/:id/edit(.:format) employees#edit
company_employee GET /companies/:company_id/employees/:id(.:format) employees#show
PATCH /companies/:company_id/employees/:id(.:format) employees#update
PUT /companies/:company_id/employees/:id(.:format) employees#update
DELETE /companies/:company_id/employees/:id(.:format) employees#destroy
companies GET /companies(.:format) companies#index
POST /companies(.:format) companies#create
new_company GET /companies/new(.:format) companies#new
edit_company GET /companies/:id/edit(.:format) companies#edit
company GET /companies/:id(.:format) companies#show
PATCH /companies/:id(.:format) companies#update
PUT /companies/:id(.:format) companies#update
DELETE /companies/:id(.:format) companies#destroy
root GET / welcome#index
companies_new GET /companies/new(.:format) companies#new
Company show.html.erb
<h3><%= #company.name %></h3>
<p><%= #company.details %></p>
<h3>Employees</h3>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Forename</th>
<th>Surname</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% for employee in #company.employees %>
<tr>
<td><%= employee.id %></td>
<td><%= employee.forename %></td>
<td><%= employee.surname %></td>
<td><%= link_to "Edit", edit_company_employee_path(employee), class: "btn btn-primary btn-sm" %></td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to "Add Employee", new_company_employee_path(#company), class: "btn btn-primary" %>
<%= link_to "Back to companies List", companies_path, class: "btn btn-outline-primary" %>
Please can someone help?

Try to pass #company to edit_company_employee_path.
<%= link_to "Edit", edit_company_employee_path(#company, employee), class: "btn btn-primary btn-sm" %>

Related

In Rails, show for nested resources not working

I am using nested resources. When I click on a goal that's been created, I keep getting this error:
param is missing or the value is empty: goal
And it directs me to the "params.require..." line:
private
def goal_params
params.require(:goal).permit(:text)
end
I'm not sure what's causing this. I can create and show the list. But when I click on a goal I get this error. I'm new to rails and I'm at my wit's end.
My view:
<h1>Listing goals</h1>
<table>
<tr>
<th>Text</th>
<th></th>
</tr>
<% #user.goals.each do |goal| %>
<tr>
<td><%= link_to goal.text, user_goals_path(#user, #goal)%></td>
</tr>
<% end %>
</table>
<h2>Add a comment:</h2>
<%= form_for([#user, #user.goals.build]) do |form| %>
<p>
<%= form.text_area :text %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
My controller:
class GoalsController < ApplicationController
def index
#user = User.find(params[:user_id])
#goal = #user.goals.find(goal_params)
end
def show
#user = User.find(params[:user_id])
#goal = #user.goals.find(:id)
#also tried goal_params and :goal_id instead of :id
end
def new
#user = User.find(params[:user_id])
#goal = #user.goals.new
end
def create
#user = User.find(params[:user_id])
#goal = #user.goals.build(goal_params)
#goal.user = current_user
if #goal.save
redirect_to new_user_goal_path, notice: "Success!~"
else
redirect_to new_user_goal_path, alert: "Failure!"
end
#to root_path
end
private
def goal_params
params.require(:goal).permit(:text)
end
end
My routes:
Rails.application.routes.draw do
devise_for :users
resources :user do
resources :goals
end
devise_scope :user do
authenticated :user do
root 'home#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
end
My show.html.erb:
<p>
<strong>Text:</strong>
<%= #goal.text %>
</p>
First thing, in the show
#goal = #user.goals.find(:id)
Should be
#goal = #user.goals.find(params[:id])
You said you tried with #user.goals.find(goal_params) in show action and I see it in your index action also. This will call the goal_params method, which require params[:goal] while your index or show request does not send to server, only when you submit the form, you will have that params. This is the cause of your error.
Second thing, your index should use
#goals = #user.goals
INSTEAD OF
#goal = #user.goals.find(goal_params)
Also, the strong parameters is used for create and update actions only to avoid mass assignment to our database. It's not used to find a record.

Trying to create comments. (Undefined method 'comment')

I am receiving this error and I don't understand as I have defined the method in the comments controller, haven't I?
I am getting slightly confused to why it is not working.
Comments controller:
class CommentsController < ApplicationController
def create
#story = Story.find(params[:story_id])
#comment = #story.comments.create(params[:comment].permit(:name, :body))
redirect_to root_path
end
end
Stories Controller:
class StoriesController < ApplicationController
before_action only: [:destroy, :show, :edit, :update]
def index
#stories = Story.order('created_at DESC')
end
def new
#story = current_user.stories.build
end
def create
#story = current_user.stories.build(story_params)
if #story.save
flash[:success] = "Your beautiful story has been added!"
redirect_to root_path
else
render 'new'
end
end
def edit
#story = Story.find(params[:id])
end
def update
#story = Story.find(params[:id])
if #story.update_attributes(params.require(:story).permit(:name, :description))
flash[:success] = "More knowledge, more wisdom"
redirect_to root_path
else
render 'edit'
end
end
def destroy
#story = Story.find(params[:id])
if #story.destroy
flash[:success] = "I think you should have more confidence in your storytelling"
redirect_to root_path
else
flash[:error] = "Can't delete this story, sorry"
end
end
def show
#stories = Story.all
end
private
def story_params
params.require(:story).permit(:name, :description)
end
end
Index.html.erb:
<p id="notice"><%= notice %></p>
<h1>This is a list of posts</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #stories.each do |story| %>
<tr>
<td><%= story.name %></td>
<td><%= story.description %></td>
<td><%= story.user.username %></td>
<td><%= link_to 'Show', story %></td>
<% if user_signed_in? %>
<td><%= link_to 'Edit', edit_story_path(story)%></td>
<td><%= link_to 'Destroy', story_path(story),method: :delete,data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
</tbody>
</table>
<h2><%= #story.comments.count %>Comments</h2>
<%= render #story.comments %>
<h3>Add a comment</h3>
<%= render 'comments/form' %>
<%= link_to 'New Story', new_story_path %>
Story Controller:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
# GET /comments.json
def index
#comments = Comment.all
end
# GET /comments/1
# GET /comments/1.json
def show
#comments = #story.comments.all
#comment = #stroy.comments.build
end
# GET /comments/new
def new
#comment = Comment.new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#story = Story.find(params[:story_id])
#story.comments.create(comment_params)
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to #comment, notice: 'Comment was successfully updated.' }
format.json { render :show, status: :ok, location: #comment }
else
format.html { render :edit }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_url, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:user_name, :body, :story_id)
end
end
Make sure you have run the right migrations
rails g scaffold comment user_name:string body:text story:references
now
rake db:migrate
In your story model write
has_many :comments
And in your comment model make sure you have
belongs_to :story
or in your story controller in the show method have this
#comments = #story.comments.all
#comment = #stroy.comments.build
And now in your story form show views, something like this
<h3>Comments</h3>
<% #comments.each do |comment| %>
<div>
<p><%= comment.body %></p>
</div>
<% end %>
<%= render 'comments/form' %>
In your comment/_form.html.erb add
<%= f.hidden_field :story_id %>
If you want to display on your index edit you like so
<tbody>
<% #stories.each do |story| %>
<tr>
<td><%= story.name %></td>
<td><%= story.description %></td>
<td><%= story.user.username %></td>
<td><%= link_to 'Show', story %></td>
<% if user_signed_in? %>
<td><%= link_to 'Edit', edit_story_path(story)%></td>
<td><%= link_to 'Destroy', story_path(story),method: :delete,data: { confirm: 'Are you sure?' } %></td>
<% story.comments.each do |c| %>
<%= c.body %>
<% end %>
<% end %>
</tr>
</tbody>
You have to start by understanding how associations works:
One Story will have many comments.
You have to define the association in the model:
class Story < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :story
end
Then the methods in the controller will be available:
class CommentsController < ApplicationController
def create
#story = Story.find(params[:story_id])
#story.comments.create(comment_params)
end
end
And in your app/stories/show.html.erb view:
<% #story.comments.each do |comment| %>
<%= comment.body #or the comment content method %>
<% end %>

Render data from my model RAILS

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

ActionController::UrlGenerationError routing error

I set up a Rails toy to play with Twitter API, but already having challenges right from the start. My files look like this:
routes.rb
Rails.application.routes.draw do
devise_for :users
root to: 'accounts#index'
resources :accounts do
resources :posts
end
end
account.rb
class Account < ActiveRecord::Base
belongs_to :user
has_many :posts
accepts_nested_attributes_for :posts
validates :name, :description, presence: :true
end
post.rb
class Post < ActiveRecord::Base
belongs_to :account
validates :tweet, presence: true
end
accounts_controller.rb
class AccountsController < ApplicationController
before_action :authenticate_user!
def index
#accounts = Account.all
#user = current_user
end
def new
#account = Account.new
end
def create
#account = Account.new(account_params)
#account.user = current_user
if #account.save
flash[:notice] = "Account succesfully created."
redirect_to #account
else
flash.now[:alert] = "Oops, something went wrong!"
render 'new'
end
end
def show
#account = Account.find(params[:id])
end
def update
end
def destroy
end
private
def account_params
params.require(:account).permit(:name, :description, posts_attributes: [:tweet])
end
end
post_controller.rb
class PostsController < ApplicationController
before_action :set_account
def index
#posts = Post.all
end
def new
#post = Post.new
end
def create
#post = #account.posts.build(post_params)
if #post.save
flash[:notice] = "Tweet created successfully."
redirect_to [#account, #post]
else
flash.now[:alert] = "Something went wrong."
render 'new'
end
end
def edit
#post = Post.find(params[:id])
end
def update
if #post.update
flash[:notice] = "Tweet updated."
redirect_to [#account, #post]
else
flash.now[:alert] = "Something is not right!"
render 'edit'
end
end
def destroy
end
def show
#post = Post.find(params[:id])
end
private
def post_params
params.require(:post).permit(:tweet)
end
def set_account
#account = Account.find(params[:account_id])
end
end
The tricky part is here:
What I am trying to do here is on the accounts page, when a user clicks on the account name, he should be redirects to the new action of the Posts controller that will allow him to create a new post for the account in question. Somehow, I am not sure how to pass the :account_id parameter.
views/accounts/index.html.erb
<table>
<tr>
<th>Account Name</th>
<th>Description</th>
<th>Tweets</th>
</tr>
<% #user.accounts.each do |account| %>
<tr>
<td><%= link_to account.name, new_account_post_path(#account) %></td>
<td><%= account.description %></td>
<td><%= account.posts.count %></td>
</tr>
<% end %>
</table>
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
<%= link_to "Create new account", new_account_path %>
Error in browser:
You need to change
<%= link_to account.name, new_account_post_path(#account) %>
to
<%= link_to account.name, new_account_post_path(account) %>
Use this code:
<% #user.accounts.each do |account| %>
<tr>
<td><%= link_to account.name, new_account_post_path(account) %></td>
<td><%= account.description %></td>
<td><%= account.posts.count %></td>
</tr>
<% end %>

Rails - Namespace params ID not found

I set up posts in a folder called 'contents' and then it fell over when I tried to delete the records. Why am I getting this error?
No route matches {:action=>"edit", :controller=>"content/stories", :id=>nil} missing required keys: [:id]
Routes.rb
namespace :content do
resources :posts
end
PostsController
def index
#posts = Post.all
end
def new
#post = Post.new
end
def create
#post = current_user.posts.new(post_params)
if #post.save
redirect_to content_posts_path
else
redirect_to root_path, notice: #post.errors.full_messages.first
end
end
def show
end
def delete
#post = Post.find(params[:id])
end
def destroy
post = Post.find(params[:id]).destroy
redirect_to :back
end
private
def post_params
params.require(:post).permit(:content)
end
end
show.html
<ol>
<% for p in #posts %>
<li>
<%= p.title %>
<%= link_to 'Edit', edit_content_post_path(#post) %>
<%= link_to 'Delete', content_post_path(#post), method: :delete %>
</li>
<% end %>
</ol>
#post is not defined, you probably need to use p in place of #post.
Also in your show.html which corresponds to show action, not sure how you are getting #posts.

Resources