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
Related
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 %>
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.
I'm trying to enter a list of new modules and when I press 'new module list' which should take me to the form to fill out it throws up the error from the title. The application trace points at the bottom, the code inside 'def module_list_params' and also just above it where 'def set_student' is. I have no idea why it's doing it. I'm using ruby on rails.
class ModuleListsController < ApplicationController
before_action :set_module_list, only: [:show, :edit, :update, :destroy]
before_action :set_student, only: [:new, :create]
# GET /module_lists
# GET /module_lists.json
def index
#module_lists = ModuleList.all
end
# GET /module_lists/1
# GET /module_lists/1.json
def show
end
# GET /module_lists/new
def new
#module_list = #student.module_lists.new
end
# GET /module_lists/1/edit
def edit
end
# POST /module_lists
# POST /module_lists.json
def create
#module_list = #student.module_lists.new(module_list_params)
respond_to do |format|
if #module_list.save
format.html { redirect_to #module_list, notice: 'Module successfully created.' }
format.json { render :show, status: :created, location: #module_list }
else
format.html { render :new }
format.json { render json: #module_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /module_lists/1
# PATCH/PUT /module_lists/1.json
def update
respond_to do |format|
if #module_list.update(module_list_params)
format.html { redirect_to #module_list, notice: 'Module list was successfully updated.' }
format.json { render :show, status: :ok, location: #module_list }
else
format.html { render :edit }
format.json { render json: #module_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /module_lists/1
# DELETE /module_lists/1.json
def destroy
#module_list.destroy
respond_to do |format|
format.html { redirect_to module_lists_url, notice: 'Module list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_module_list
#module_list = ModuleList.find(params[:id])
end
def module_list_params
params.require(:module_list).permit(:student_id, :title, :description, :credit_value)
end
def set_student
#student = Student.find_by(id: params[:student_id]) ||
Student.find(module_list_params[:student_id])
end
end
Rake routes screenshot
I believe your issue is the line before_action :set_student, only: [:new, :create]. set_student is being run when you go to the page with the form, but since there is no student_id included in the URL, it can't find anything to set it to.
To create a dependent object, there are two main ways: you can either have a form page tied to a specific parent object already, ie /students/4/module_lists/new, in which case submitting the form will create a module list tied to the student with an ID of 4. The other way is to have a general form not tied to any specific parent object, with some way of selecting a parent inside the form, eg a select or something. In that case the url would just be something like /module_lists/new.
If you want to go the first route, you'll want to nest the resources :module_lists inside of students. Check out the docs for how to do that, but it would basically look like
resources :students do
resources :module_list
end
And then in the link_to you click to go to that page, you'll need to pass in the student_id:
link_to 'Create Module List', new_student_module_list_path(#student)
For the second option, you can just remove :new from the before_action, change the new method to
def new
#module_list = ModuleList.new
end
And then add a way of picking which student to tie it to to the form.
I am able to soft delete an user from the main application.
Here are the details.
The user URL is:
http://0.0.0.0:3000/users/4c7fa12c-3d58-480b-a823-6c67d6e7f0fe.json
Which is presenting a JSON result like this:
{"id":"4c7fa12c-3d58-480b-a823-6c67d6e7f0fe","name":"John","status":"Active","created_at":"2015-11-10T18:31:27.000+00:00","updated_at":"2015-11-10T18:38:20.000+00:00"}
I can do a soft delete by using an inactivation this way:
http://0.0.0.0:3000/users/4c7fa12c-3d58-480b-a823-6c67d6e7f0fe/inactivate
Here is my inactivate method in the users controller:
def inactivate
#user.update status: 'Inactive'
redirect_to users_url
end
The result is shown when reload the user URL:
{"id":"4c7fa12c-3d58-480b-a823-6c67d6e7f0fe","name":"John","status":"Inactive","created_at":"2015-11-10T18:31:27.000+00:00","updated_at":"2015-11-10T19:29:58.000+00:00"}
Now my user is "Inactive".
Here is my routes file:
Rails.application.routes.draw do
resources :wit_dims
resources :wokas
resources :posts
resources :languages
resources :users
root :to => "home#index"
resources :users do
get 'inactivate', on: :member
end
match 'inactivate', to: 'users#inactivate', via: 'delete'
#api
namespace :api do
namespace :v1 do
resources :users, only: [:index, :create, :show, :update, :destroy]
resources :posts, only: [:index, :create, :show, :update, :destroy]
end
end
end
How I can change this routes file and the API users controller to make the same king of inactivation through the API? I want more than a trivial solution using a PUT to change status of the user from Active to Inactive.
Here is my main application users controller:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy, :inactivate]
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was 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
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully inactivated.' }
format.json { head :no_content }
end
end
def inactivate
#user.update status: 'Inactive'
redirect_to users_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params[:user]
end
end
Here is my API users controller:
class Api::V1::UsersController < Api::V1::BaseController
before_action :set_user, only: [:show, :update, :destroy]
def show
render(json: Api::V1::UserSerializer.new(#user).to_json)
end
def update
if #user.update_attributes(user_params)
render(
json: Api::V1::UserSerializer.new(#user).to_json,
status: 200,
location: api_v1_user_path(#user.id)
)
else
return api_error(status: 422, errors: #tbm.errors)
end
end
def index
users = User.all
render(
json: ActiveModel::ArraySerializer.new(
users,
each_serializer: Api::V1::UserSerializer,
root: 'users'
)
)
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :status).delete_if{ |k,v| v.nil? }
end
end
Basically I would like to be able to call an inactivate method through the API which is going to change the status from Active to Inactive, instead of physically deleting / destroying the user.
I used PUT and executed an updated on the status attribute to mark the user as Inactive.
After performing a rails g scaffold Project name:string, I get a routing error when I create a new project.
My steps:
1) on /projects, I click 'New Project'.
2) I fill the project details and click 'Create Project'.
In this step the form seems to be correct:
form accept-charset="UTF-8" action="/projects" class="new_project" id="new_project" method="post"
3) I get the following error (routing error): No route matches [POST] "/projects/new"
Whereas:
when I reload the /projects/new page, the creation of the project works fine
Any reason for this?
Below are the files I have (I created most of them with the scaffolding)
app/models/project.rb:
class Project < ActiveRecord::Base
end
app/controllers/projects_controller.rb: (I only show here the methods that we re interested in)
class ProjectsController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
before_action :set_project, only: [:show, :edit, :update, :destroy]
# GET /projects/new
def new
#project = Project.new
end
# GET /projects/1/edit
def edit
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 action: 'show', status: :created, location: #project }
else
format.html { render action: '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 { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
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)
end
end
and config/routes.rb:
Testproject::Application.routes.draw do
devise_for :users
resources :projects
root 'projects#index'
end
Thanks for your help