create new devise user from another non devise controller - ruby-on-rails

I have a users table (Devise) , with a column "admin" (boolean) to qualify my users.
I also have a namespace "Backend".
I would like that my admins users can create new users from the backend namespace.
So I created a Backend::UsersController :
class Backend::UsersController < ApplicationController
layout 'admin'
before_filter :authenticate_user!
def index
#auteurs = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #auteurs }
end
end
def new
#auteur = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #auteur }
end
end
def create
#auteur = User.new(params[:auteur])
respond_to do |format|
if #auteur.save
format.html { redirect_to #auteur, notice: 'Article was successfully created.' }
format.json { render json: #auteur, status: :created, location: #auteur }
else
format.html { render action: "new" }
format.json { render json: #auteur.errors, status: :unprocessable_entity }
end
end
end
end
Here's the "_form" partial called in the "new" view :
<%= simple_form_for(#auteur) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :email %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
An here's my routes :
namespace :backend do
resources :articles
root to: "articles#index"
resources :accueil
resources :users
get "users/index"
get "users/create"
get "users/new"
end
devise_for :users
But when I try to access to "backend/users/new", it drives me to this error :
NoMethodError in Backend/users#new
Showing C:/Ruby/acturevue/app/views/backend/users/_form.html.erb where line #1 raised:
undefined method `users_path' for #<#<Class:0x39616b0>:0x416f6d0>
Does somebody have any ideas of the source of the problem ?
Thanks
UPDATE
So, I modified my code like that :
In Backend::UsersController :
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user}
end
end
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to backend_users_path(#user), notice: 'Article was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
In _form :
<%= simple_form_for(#user) do |f| %>
But I still have the error.
However the backend_users_path exists in y routes :
backend_users GET /backend/users(.:format) backend/users#
index
POST /backend/users(.:format) backend/users#
create
new_backend_user GET /backend/users/new(.:format) backend/users#
new
edit_backend_user GET /backend/users/:id/edit(.:format) backend/users#
edit
backend_user GET /backend/users/:id(.:format) backend/users#
show
PUT /backend/users/:id(.:format) backend/users#
update
DELETE /backend/users/:id(.:format) backend/users#
destroy

You need to use the namespace in your redirect:
redirect_to [:backend, #auteur] #...
See my answer to this question.

Related

rails: nested resources saving empty records

I have created a simple form of nested resources. I can't get the child form todo_item to save correctly. When I click the "create todo item" button, an empty record will be created and saved no matter what I put in the title field.
The code is really simple and the parent record is saving fine. the child records are displaying so I can't figure out what could be wrong. Please help.
My models:
class TodoItem < ActiveRecord::Base
belongs_to :todo_list
end
class TodoList < ActiveRecord::Base
has_many :todo_items, dependent: :destroy
end
My controllers:
class TodoItemsController < ApplicationController
before_action :set_todo_list
before_action :set_todo_item, only: [:show, :edit, :update, :destroy]
def new
#todo_item = #todo_list.todo_items.new
end
def create
#todo_item = #todo_list.todo_items.new
respond_to do |format|
if #todo_list.save
format.html { redirect_to #todo_list, notice: 'Todo item was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
private
def set_todo_item
#todo_item = #todo_list.todo_items.find(params[:id])
end
def set_todo_list
#todo_list = TodoList.find(params[:todo_list_id])
end
def todo_item_params
params.require(:todo_item).permit(:title, :due_date, :description, :text, :completed)
end
end
View.html.erb:
<h1>New Todo Item</h1>
<%= render 'form' %>
<%= link_to 'Back', #todo_list %>
_form.html.erb:
<%= form_for([#todo_list, #todo_item]) do |f| %>
...
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You initialize the #todo_item here:
def create
#todo_item = #todo_list.todo_items.new # <===== INITIALIZED HERE
respond_to do |format|
if #todo_list.save # <===== SAVED HERE WITHOUT EVER ASSIGNING VALUES.
format.html { redirect_to #todo_list, notice: 'Todo item was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
But, don't provide any arguments to new. So, the new record has no values.
Instead, do something more like:
#todo_item = #todo_list.todo_items.new(todo_item_params)
Perhaps you should also add some validations so you could avoid this situation.
You need to modify the create method:
def create
#todo_item = #todo_list.todo_items.create(todo_item_params)
respond_to do |format|
if #todo_list.save
format.html { redirect_to #todo_list, notice: 'Todo item was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end

Rendering a partial form on a static page

I have a static page I named home and used scaffold to generate a form called Specialists and when I try to render the form using the following code
<%= render :partial => 'specialists/form', locals: {specialist: #specialist} %>
I get the following error undefined method "errors" for nil:NilClass and here is the code snippet of the error
Extracted source (around line #2):
<%= form_with(model: specialist, local: true) do |form| %>
<% if specialist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(specialist.errors.count, "error") %> prohibited this specialist from being saved:</h2>
<ul>
I tried to check previous similar questions but none of them had this error because of this, I am pretty new to Ruby on Rails.
Controller code
class SpecialistsController < ApplicationController
before_action :set_specialist, only: [:show, :edit, :update, :destroy]
# GET /specialists
# GET /specialists.json
def index
#specialists = Specialist.all
end
# GET /specialists/1
# GET /specialists/1.json
def show
end
# GET /specialists/new
def new
#specialist = Specialist.new
end
# GET /specialists/1/edit
def edit
end
# POST /specialists
# POST /specialists.json
def create
#specialist = Specialist.new(specialist_params)
respond_to do |format|
if #specialist.save
format.html { redirect_to #specialist, notice: 'Specialist was successfully created.' }
format.json { render :show, status: :created, location: #specialist }
else
format.html { render :new }
format.json { render json: #specialist.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /specialists/1
# PATCH/PUT /specialists/1.json
def update
respond_to do |format|
if #specialist.update(specialist_params)
format.html { redirect_to #specialist, notice: 'Specialist was successfully updated.' }
format.json { render :show, status: :ok, location: #specialist }
else
format.html { render :edit }
format.json { render json: #specialist.errors, status: :unprocessable_entity }
end
end
end
# DELETE /specialists/1
# DELETE /specialists/1.json
def destroy
#specialist.destroy
respond_to do |format|
format.html { redirect_to specialists_url, notice: 'Specialist was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_specialist
#specialist = Specialist.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def specialist_params
params.require(:specialist).permit(:firstname, :lastname, :phone, :email, :interest)
end
end'
Try the following
On the controller, I think missing something, try the following
def new
#specialist = Specialist.new
end
On the form
<%= form_with model: #specialist, local: true do |form| %>
Or update form like below
<%= form_with scope: :specialist, url: specialists_path, local: true do |form| %>
Rails 5 guides say about validation see here
About form_with you can learn more the following link
Hope it helps

Rails: No route matches [PATCH]

I ran into a very strange bug in my Rails app: Whenever I try to submit a form I get the error No route matches [PATCH] "/business_cases" (in this case). But after clicking the "Back"-Button in my Browser and filling out + submitting again, it works fine. As this error appears not only in this specific model but almost every other I'm quite lost.. Here is the example.
routes:
business_cases GET /business_cases(.:format) business_cases#index
POST /business_cases(.:format) business_cases#create
new_business_case GET /business_cases/new(.:format) business_cases#new
edit_business_case GET /business_cases/:id/edit(.:format) business_cases#edit
business_case GET /business_cases/:id(.:format) business_cases#show
PATCH /business_cases/:id(.:format) business_cases#update
PUT /business_cases/:id(.:format) business_cases#update
DELETE /business_cases/:id(.:format) business_cases#destroy
routes.rb:
root 'dashboards#index'
get "index" => "pages#index"
resources :users, :orders, :sales, :business_cases
controller (FYI: I use cancancan):
class BusinessCasesController < ApplicationController
load_and_authorize_resource
before_action :authenticate_user!
def index
end
def show
end
def new
end
def edit
end
def create
respond_to do |format|
if #business_case.save
format.html { redirect_to business_cases_url, notice: 'Business case was successfully created.' }
format.json { render :show, status: :created, location: #business_case }
else
format.html { render :new }
format.json { render json: #business_case.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #business_case.update(business_case_params)
format.html { redirect_to business_cases_url, notice: 'Business case was successfully updated.' }
format.json { render :show, status: :ok, location: #business_case }
else
format.html { render :edit }
format.json { render json: #business_case.errors, status: :unprocessable_entity }
end
end
end
def destroy
#business_case.destroy
respond_to do |format|
format.html { redirect_to business_cases_url, notice: 'Business case was successfully destroyed.' }
format.json { head :no_content }
end
end
model:
class BusinessCase < ActiveRecord::Base
validates :name, :description, :presence => true
end
form (shorten):
<%= form_for #business_case, html: { multipart: true } do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: "form-control", placeholder: "X-Sell" %>
</div>
<% end %>

No route matches [PATCH] "/admin/roles.4"

I made model Role with rolify gem.
But controller made to namespace :admin :
class Admin::RolesController < ApplicationController
def index
#roles = Role.all
end
def new
#role = Role.new
end
def create
#role = Role.new(role_params)
respond_to do |format|
if #role.save
format.html { redirect_to admin_role_path(#role), notice: 'Роль создана.' }
format.json { render action: 'show', status: :created, location: #role }
else
format.html { render action: 'new' }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
def show
#role = Role.find(params[:id])
end
def edit
#role = Role.find(params[:id])
end
def update
respond_to do |format|
if #role.update(role_params)
format.html { redirect_to admin_role_path(#role), notice: 'Роль обновлена.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
def destroy
#role = Role.find(params[:id])
#role.destroy
respond_to do |format|
format.html { redirect_to admin_roles_url }
format.json { head :no_content }
end
end
private
def set_role
#role = Role.find(params[:id])
end
def role_params
params.require(:role).permit(:name)
end
end
When I want to update Role, I open form, edit, click submit and get error:
Routing Error
No route matches [PATCH] "/admin/roles.4"
Please help me.
Based on the form code you pasted above, you'll see that url is pointing to the path used for creates but not updates.
You should be able to update your call to simple_form like so:
= simple_form_for [:admin, #role], :html => { :class => 'form-horizontal' } do |f|
You'll see that you can pass an array with symbolized namespace names and the object instance, and it'll build the URL correctly for both POSTs and PATCHes.
Problem is solved.
In _form I fix url.
= simple_form_for #role, url: admin_role_path(#role), :html => { :class => 'form-horizontal' } do |f|

Ruby on Rails - Passing Parameters between methods

Routes File:
resources :tournaments do
resources :game, :only => [:new, :index, :create, :update, :destroy]
end
Rake Routes shows:
new_tournament_game GET /tournaments/:tournament_id/game/new(.:format) game#new
I call:
<td><%= link_to 'Add Game', new_tournament_game_path(tournament) %></td>
Game Model:
Takes me to the view game view with the URL:
http:// local host:3000/tournaments/2/game/new
And view:
<h1>New Game in <%= #tournament.name %> Tournament</h1>
<fieldset>
<%= form_for [:tournament, #game], :url => tournament_game_index_path do |f| %>
<table>
<td>
.... More fields .....
</td>
<div class="form-actions">
<%= f.submit "Create %>
</div>
<% end %>
When create is clicked it yields the error:
undefined method `game_url' for #<GamesController:0xb6131e40>
Questions:
Should I be using nested routes or hidden fields?
Do I need a separate tournament_game controller / view to handle the tournament game calls?
How do I get it to look for the correct create route when clicking the Create button?
When I want to have a relationship between two tables, do I only need the nested resource and the has_many / belongs_to calls or do I still need a foreign key column such as Tournament?
Sorry for all of the questions in one thread. Any help you can offer would be greatly appreciated!
Thank you.
Edit:
The error references line 39 which would be the line for the create controller.
class GamesController < ApplicationController
# GET /game
# GET /game.json
def index
#game = Game.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #game }
end
end
# GET /game/1
# GET /game/1.json
def show
#game = Game.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #game }
end
end
# GET /game/new
# GET /game/new.json
def new
#game = Game.new
#tournament = Tournament.find(params[:tournament_id])
end
# GET /game/1/edit
def edit
#game = Game.find(params[:id])
end
# POST /game
# POST /game.json
def create
#tournament = Tournament.find(params[:tournament_id])
#game = #tournament.game.build(params[:game])
respond_to do |format|
if params[:commit] != 'Cancel'
if #game.save
format.html { redirect_to #game, notice: 'Game was successfully created.' }
format.json { render json: #game, status: :created, location: #game }
format.json { render json: #game }
else
format.html { render action: "new" }
format.json { render json: #game.errors, status: :unprocessable_entity }
end
else
format.html { redirect_to #game, alert: 'Game was not updated.' }
end
end
end
# PUT /game/1
# PUT /game/1.json
def update
#game = Game.find(params[:id])
respond_to do |format|
if params[:commit] != 'Cancel'
if #game.update_attributes(params[:game])
format.html { redirect_to #game, notice: 'Game was successfully updated.' }
format.json { render json: #game }
else
format.html { render action: "edit" }
format.json { render json: #game.errors, status: :unprocessable_entity }
end
else
format.html { redirect_to #game, alert: 'Game was not updated.' }
end
end
end
# DELETE /game/1
# DELETE /game/1.json
def destroy
#game = Game.find(params[:id])
#game.destroy
respond_to do |format|
format.html { redirect_to game_url }
format.json { head :no_content }
end
end
end
Try this:
<%= form_for #game, :url => tournament_games_path(#tournament) do |f| %>
This will call the create method of games controller
Game Controller:
def create
#tournament = Tournament.find(params[:tournament_id])
#game = #tournament.games.build(params[:game])
if #game.save
flash[:success] = "Game created successfully"
redirect_to tournaments_path
else
render new_tournament_game_path
end
end
Routes:
resources :tournaments do
resources :games, :only => [:new, :index, :create, :update, :destroy]
end

Resources