Ruby on Rails "Couldn't find Customer with 'id'=links" - ruby-on-rails

I want to have a page that displays links to other websites in my project. I created links.html.erb in my customers views but when I try access the page I get this error.
ActiveRecord::RecordNotFound in CustomersController#show
Couldn't find Customer with 'id'=links
Customers Controller:
class CustomersController < ApplicationController
before_action :set_customer, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /customers
# GET /customers.json
def index
#customers = Customer.all
#q = Tour.search(params[:q])
#tours = #q.result.page(params[:page]).per(5)
#q.build_condition if #q.conditions.empty?
#q.build_sort if #q.sorts.empty?
end
def links
end
# GET /customers/1
# GET /customers/1.json
def show
#customers = Customer.all
end
def welcome
end
# GET /customers/new
def new
#customer = Customer.new
end
# GET /customers/1/edit
def edit
end
# POST /customers
# POST /customers.json
def create
#customer = Customer.new(customer_params)
respond_to do |format|
if #customer.save
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /customers/1
# PATCH/PUT /customers/1.json
def update
respond_to do |format|
if #customer.update(customer_params)
format.html { redirect_to #customer, notice: 'Customer was successfully updated.' }
format.json { render :show, status: :ok, location: #customer }
else
format.html { render :edit }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# DELETE /customers/1
# DELETE /customers/1.json
def destroy
#customer.destroy
respond_to do |format|
format.html { redirect_to customers_url, notice: 'Customer record successfully deleted' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_customer
#customer = Customer.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def customer_params
params.require(:customer).permit(:name, :address, :telephone_no, :ticket_number)
end
end
Routes:
Rails.application.routes.draw do
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
resources :customers
resources :tours
devise_for :users
root 'customers#welcome'
In view:
<% if current_user.customer? %>
<div class="col-sm-4">
<%= link_to image_tag("image1.jpg", size: "300x300"), {:controller => 'customers', :action => "links" } %>
<h3>Links</H3>
</div>
<% end %>
Anyone help with what is wrong here? Thanks.

Add get 'links' => 'customers#links', as: :link to the routes.rb and update your link as:
<%= link_to image_tag("image1.jpg", size: "300x300"), link_path %>

Here's a bit of an expansion on Ganesh's answer.
When you do this:
<%= link_to image_tag("image1.jpg", size: "300x300"), {:controller => 'customers', :action => "links" } %>
You're creating a url to:
customers/links
In your routes, the first match for customers/links is customers/:id which routes to customers/show with params[:id] = 'links'. See the Guide if you don't understand why this is true. That's why you're getting the error:
ActiveRecord::RecordNotFound in CustomersController#show
Couldn't find Customer with 'id'=links
As Ganesh correctly points out, you can coerce the routes exactly as he says. To me, it is a little smelly to put this links page in the CustomerController and to coerce the routes. But, that's really a design decision based on the problem(s) you're trying to solve.

Related

Cannot delete records in Rails

I have three models: Project, team and users.
Team has many projects associated.
In my projects def I want to delete teams associated to projects but nothing happens when I click delete.
My destroy def is as follows:
def destroy
#project = Project.find(params[:id])
#team = project.team
#project.destroy
# edit #1 shown below:
respond_to do |format|
format.html { redirect_to #team, notice: 'Project was successfully destroyed.' }
end
end
And making the button inside show.erb.html to delete project and link back to project path
<%= link_to 'Delete Project', project_path(#project), data: { confirm: 'Are you sure'}, method: :destroy, class:'button is-danger is-outlined' %>
</div>
Routes:
Rails.application.routes.draw do
resources :projects
resources :teams
as :user do
put '/user/confirmation' => 'confirmations#update', :via => :patch, :as => :update_user_confirmation
end
devise_for :users, controllers: {
registrations: 'registrations',
confirmations: 'confirmations'
}
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
root 'home#index'
end
I'm still very new to rails and cannot find a reason for why this may be occuring.
Edit 2 - More details
Projects Controller is as follows:
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, only: [:edit, :update, :destroy]
# GET /projects
# GET /projects.json
def index
#projects = Project.all.order('created_at DESC')
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
#project = current_user.projects.build
#teams = Team.where('id = ?', current_user.team_id)
end
# GET /projects/1/edit
def edit
#teams = current_user.teams
end
# POST /projects
# POST /projects.json
def create
#project = current_user.projects.build(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
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
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project = Project.find(params[:id])
#team = project.team
#project.destroy
# edit #1 shown below:
respond_to do |format|
format.html { redirect_to #team, notice: 'Project was successfully destroyed.' }
end
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(:name, :description, :team_id)
end
end
Redirecting to a resource after you delete it doesn't work, because that resource no longer exists. So the controller action should probably redirect to the deleted projects team:
def destroy
#project = Project.find(params[:id])
#team = project.team
#project.destroy
# edit #1 shown below:
respond_to do |format|
format.html { redirect_to #team, notice: 'Project was successfully destroyed.' }
end
end
Then your link_to should use method: :delete, NOT method: :destroy:
<%= link_to 'Delete Project', project_path(#project), data: { confirm: 'Are you sure'}, method: :delete, class:'button is-danger is-outlined' %>
Ref: https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to-label-Options
See if that gets you going, and if not please share some debugging information.
Edit #1:
In your controllers destroy action, you need to do a little more work to handle how rails responds to requests. I didn't notice it missing before but the action should have a respond_to block where you can choose to respond different ways basically. I modified the above controller action code to give you an example.

Rails nested route with shallow and empty path - can't edit entry

This is the first time I've used nested routes with shallow and I'm struggling to get my edit action to work (I'm also learning more Rails stuff).
So a group can have multiple group actions assigned to it, so my route is set up as
resources :groups do
get 'actions', to: 'group_actions#index', as: :actions
get 'actions/new', to: 'group_actions#new', as: :new_action
post 'actions', to: 'group_actions#create'
resources :group_actions, path: '', as: :actions, except: [:index, :new, :create], shallow: true, shallow_path: 'actions/:group_id'
end
The reason for the empty path is so we can easily manage conflicting group action names by appending the group_id before it, so an action URL would be...
/actions/17/action-name
for example. This of course causes an issue with the index/new actions within a nested route so I manually set those routes as above. This all seems to work fine, actions can be created, deleted, viewed etc but I can't edit them.
This gives me the following routes...
group_actions GET /groups/:group_id/actions(.:format) group_actions#index
group_new_action GET /groups/:group_id/actions/new(.:format)
group_actions#new
POST /groups/:group_id/actions(.:format) group_actions#create
edit_action GET /actions/:group_id/:id/edit(.:format) group_actions#edit
action GET /actions/:group_id/:id(.:format) group_actions#show
PATCH /actions/:group_id/:id(.:format)group_actions#update
PUT /actions/:group_id/:id(.:format) group_actions#update
DELETE /actions/:group_id/:id(.:format)
My GroupAction controller is as so...
class GroupActionsController < ApplicationController
before_action :authenticate_user!, :except => [:show, :index]
before_action :set_group, only: [:index, :show, :new, :create, :edit, :update, :destroy]
def index
#group_actions = GroupAction.all
end
def show
#group_action = GroupAction.find(params[:id])
end
def new
#group_action = #group.group_actions.build
end
def edit
#group_action = GroupAction.find(params[:id])
end
def create
#group_action = GroupAction.new(group_action_params)
respond_to do |format|
if #group_action.save
format.html { redirect_to group_actions_path(#group.slug), notice: 'Group Action successfully created.' }
format.json { render :show, status: :created, group: #group }
else
format.html { render :new }
format.json { render json: #group.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #group_action.update(group_params)
format.html { redirect_to #group_action, notice: 'Action was successfully updated.' }
format.json { render :show, status: :ok, location: #group_action }
GaTrack.event(:group, :updated, "#{#group_action.name}")
else
format.html { render :edit }
format.json { render json: #group_action.errors, status: :unprocessable_entity }
end
end
end
def destroy
#group_action = GroupAction.find(params[:id])
#group_action.destroy
respond_to do |format|
format.html { redirect_to group_actions_path(#group.slug), notice: 'Action was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_group
#group = Group.find(params[:group_id])
end
def group_action_params
params.require(:group_action).permit(:name, :description, :location, :start_date, :end_date, :how_to_participate, :intro_email, :update_email, :thank_you_email, :action_link, :is_public, :group_id)
end
end
I'm then trying to share my new/edit forms and this is where I'm not understanding the issue.
new.html.erb
<h1>New Group Action</h1>
<%= render 'form', group_action: #group_action %>
edit.html.erb
<h1>New Group Action</h1>
<%= render 'form', group_action: #group_action %>
When trying to edit an action I get the following error...
undefined method `group_action_path' for #<#
<Class:0x007f855e30b2c8>:0x007f855e3163a8>
Did you mean? group_actions_path
group_locations_path
group_new_action_path
group_actions_url
So I ended up wrapping the form in separate form_forso I could use the url option for editing, which works for now.
<%= form_for(#group_action, url: action_path) do |f| %>
<%= render 'form', f: f %>
<% end %>

Rails uninitialized constant error with mount_uploader

I am using Rails scaffold to create a simple model called Movies that contains the movie's name, director, synopsis and poster.
I am using the Carrierwave gem to upload the poster image. When I first boot up the rails server, I get the following message:
NameError in MoviesController#new
uninitialized constant Movie::PosterUploader
The extracted source the error screen displays is my models/movie.rb file:
class Movie < ApplicationRecord
mount_uploader :poster, PosterUploader
end
Here is my movies controller:
class MoviesController < ApplicationController
before_action :set_movie, only: [:show, :edit, :update, :destroy]
# 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
private
# Use callbacks to share common setup or constraints between actions.
def set_movie
#movie = Movie.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white
list through.
def movie_params
params.require(:movie).permit(:title, :director, :synopsis, :poster)
end
end
When I created the model using Rails scaffold I made the poster a string, but changed that to file in this section of Movies form partial:
<div class="field">
<%= form.label :poster %>
<%= form.file_field :poster, id: :movie_poster %>
</div>
Here is my routes file just in case I have made an error there:
Rails.application.routes.draw do
resources :movies
root 'movies#index'
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
Any help would be greatly appreciated.
uninitialized constant Movie::PosterUploader
You should generate the uploader. Do
rails generate uploader Poster
which should generate the file
app/uploaders/poster_uploader.rb

Rails error: Couldn't find Node with 'id'=index?

I generate a node to show node name, but error . Here is the codo.
controllers/nodes_controller.rb (default)
class NodesController < ApplicationController
before_action :set_node, only: [:show, :edit, :update, :destroy]
def index
#nodes = Node.all
end
def show
#node = Node.find(params[:id])
end
def new
#node = Node.new
end
def edit
end
def create
#list = Node.new(node_params)
respond_to do |format|
if #node.save
format.html { redirect_to #node, notice: 'Node was successfully created.' }
format.json { render :show, status: :created, location: #node }
else
format.html { render :new }
format.json { render json: #list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /lists/1
# PATCH/PUT /lists/1.json
def update
respond_to do |format|
if #node.update(node_params)
format.html { redirect_to #node, notice: 'Node was successfully updated.' }
format.json { render :show, status: :ok, location: #node }
else
format.html { render :edit }
format.json { render json: #node.errors, status: :unprocessable_entity }
end
end
end
# DELETE /lists/1
# DELETE /lists/1.json
def destroy
#node.destroy
respond_to do |format|
format.html { redirect_to nodes_url, notice: 'Node was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_node
#node = Node.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def node_params
params.require(:node).permit(:name, :summary)
end
end
models/node.rb
class Node < ActiveRecord::Base
has_many :lists
end
views/nodes/index.html.erb
<div class="nodes_list">
nodes: <br> <br>
<% nodes.each do |node| %>
<button class="secondary hollow button tiny">
<% if list.node %>
<%= link_to node.name, node %>
<% end %>
</button>
<% end %>
</div>
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :lists, only: [:index, :show, :new, :create]
resources :nodes, only: [:show, :index, :create, :new]
root 'lists#index'
end
rails s http://localhost:3000/nodes/index
ActiveRecord::RecordNotFound in NodesController#show
Couldn't find Node with 'id'=index
Extracted source (around line #61):
# Use callbacks to share common setup or constraints between actions.
60 def set_node
61 #node = Node.find(params[:id])
62 end
Request
Parameters:
{"id"=>"index"}
What should I do? How to debug? Thanks tell me.
You don't need to hit http://localhost:3000/nodes/index for the index action to be invoked in Rails controller. All you have to do is to go for http://localhost:3000/nodes, and it will hit the index action in your controller.
Anything like http://localhost:3000/nodes/something will take you to show action, and something will be taken as id to find a particular node. And since you are hitting: http://localhost:3000/nodes/index, so Rails is taking index as id to find a particular node.
Stick with the Rails convention, and REST principles, and let the magic of Rails take care of the things, and it sticks the following routes to particular actions:
GET: http://localhost:3000/nodes ----> Nodes#index
GET: http://localhost:3000/nodes/something ------> Nodes#show

Rails association new_path error

I have two models post and topic in my rails app
class Post < ActiveRecord::Base
#relation between topics and post
belongs_to :topic
#post is valid only if it's associated with a topic:
validates :topic_id, :presence => true
#can also require that the referenced topic itself be valid
#in order for the post to be valid:
validates_associated :topic
end
And
class Topic < ActiveRecord::Base
#relation between topics and post
has_many :posts
end
I am trying to create association between both of them.
I want multiple post corresponding to each topic
I have used nested routes
Rails.application.routes.draw do
# nested routes
resources :topics do
resources :posts
end
resources :userdetails
devise_for :users, :controllers => { :registrations => "registrations" }
My Post controller looks like
class PostsController < ApplicationController
# before_action :set_post, only: [:show, :edit, :update, :destroy]
before_filter :has_userdetail_and_topic, :only =>[:new, :create]
# GET /posts
# GET /posts.json
#for new association SAAS book
protected
def has_userdetail_and_topic
unless(#topic =Topic.find_by_id(params[:topic_id]))
flash[:warning] = 'post must be for an existing topic'
end
end
public
def new
#post = #topic.posts.build
###topic = Topic.find(params[:topic_id1])
end
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
##topic.posts << #post
##current_user = current_user.id
#current_user.posts << #topic.posts.build(params[:post])
##post = Post.new(post_params )
##post.userdetail_id = current_user.id
#Association functional between topic and post
#Class variable used
###topic.posts << #post
respond_to do |format|
if #post.save
format.html { redirect_to #post, 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
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:topic_id,:issue, :description, :rating, :userdetail_id)
end
end
I am trying to navigate from topics/index via code <td><%= link_to 'Write', new_topic_post_path(#topic) %> </td>
but when i try to go at localhost:3000/topics]
I am getting error
No route matches {:action=>"new", :controller=>"posts", :topic_id=>nil} missing required keys: [:topic_id]
Can any body tell me about this error, as i am new to rails please clearly specify answer.
And I have one more doubt, please tell me if i am doing association between topic and post incorrectly.I have confusion about this line of code -
#topic.posts << #post
What the error missing required keys: [:topic_id] is telling you is that you need to provide a hash with the key topic_id:
<%= link_to 'Write', new_topic_post_path(topic_id: #topic) %>
Passing a resource as to a route helper only works for the id param:
<%= link_to #topic, topic_path(#topic) %>
Is a kind of shorthand for:
<%= link_to #topic, topic_path(id: #topic.to_param) %>
Addition:
#prcu is also correct. The #topic record needs to be saved to the database. Records which are not saved do not have an id since the database assigns the id column when the record is inserted.
You also need to set the #topic instance variable in PostsController:
#topic = Topic.find(params[:id])
This is commonly done with a before filter:
before_filter :set_topic, only: [:new]
def set_topic
#topic = Topic.find(params[:id])
end
The same also need to be done in TopicsController#index.
#topic is not set or it's not persisted. You can not use topic not saved to db in this helper.

Resources