I have two associated tables. Venues and Specials. A venue can have many specials. Once a user has created a venue I wish to allow them to create a special on the venues#index page. By using nested resources I have achieved the desired URL: /venues/5/specials/new.
However, my current code results with: No route matches {:controller=>"specials", :format=>nil}
I'm guessing the error is with my SpecialsController and the def new and def create functions.
I would like the URL to take me to a form page where I can enter new data for the specials
<%= link_to 'Add Special', new_venue_special_path(venue) %>
App1::Application.routes.draw do
resources :venues do
resources :specials
end
def new
#venue = Venue.find(params[:venue_id])
#special = #venue.specials.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #special }
end
end
def create
#venue = Venue.find(params[:venue_id])
#special = #venue.specials.build(params[:special])
respond_to do |format|
if #special.save
format.html { redirect_to #special, notice: 'Special was successfully created.' }
format.json { render json: #special, status: :created, location: #special }
else
format.html { render action: "new" }
format.json { render json: #special.errors, status: :unprocessable_entity }
end
end
end
Backtrace
Started GET "/venues/4/specials/new" for 127.0.0.1 at 2011-12-06 23:36:01 +0200
Processing by SpecialsController#new as HTML
Parameters: {"venue_id"=>"4"}
[1m[36mVenue Load (0.2ms)[0m [1mSELECT "venues".* FROM "venues" WHERE "venues"."id" = $1 LIMIT 1[0m [["id", "4"]]
Rendered specials/_form.html.erb (1.9ms)
Rendered specials/new.html.erb within layouts/application (2.6ms)
Completed 500 Internal Server Error in 97ms
ActionView::Template::Error (No route matches {:controller=>"specials", :format=>nil}):
1: <%= form_for(#special) do |f| %>
2: <% if #special.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#special.errors.count, "error") %> prohibited this special from being saved:</h2>
app/views/specials/_form.html.erb:1:in `_app_views_specials__form_html_erb__2784079234875518470_70162904892440'
app/views/specials/new.html.erb:7:in `_app_views_specials_new_html_erb__115378566176177893_70162906293160'
app/controllers/specials_controller.rb:30:in `new'
Rendered /Users/andrewlynch/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.1.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.7ms)
redirect_to #special
this will default to "specials_path", but you're using venue_special_path
you probably want:
redirect_to [#venue, #special]
and in the form you will need the same:
<%= form_for([#venue, #special]) do |f| %>
basically - the issue is that you have a nested resource... which means that every place where you are declaring a url path (including implicit places like form_for) has to be replaced with both the #venue and the #special, instead of just the #special.
you may come across this same "bug" elsewhere in your generated scaffold code... just do the same thing and you should be good.
Related
I use Rails 5.1 and the "redirect_to #search" inside create action doesn't work.
My SearchesController:
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.create!(search_params)
redirect_to #search # search_path(#search) doesn't work either
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit!
end
end
After creating a new search entry by clicking the submit button it doesn't redirect to show page.
My app/views/searches/new.html.erb:
<div>
<h1>Advanced Search Form</h1>
<%= form_with model: #search do |form| %>
<%= form.text_field :keywords %>
<%= form.select :ort, options_from_collection_for_select(Imagecapturing.cities, :ort, :city_name, prompt: false, include_blank: false) %>
<%= form.submit("Suchen", :id=>"button", :class=>"Test", :name=>"submit") %>
<% end %>
</div>
config/routes.rb:
Rails.application.routes.draw do
root 'imagecapturings#index'
resources :searches
end
Log:
Started POST "/searches" for ::1 at 2018-06-14 17:37:54 +0200
Processing by SearchesController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"B91lIUxZZvanOx1luhhfWBJ9mAO5Np/6Bx4xzPdv2Ygj29bprWk5+wIBP7kMVl5Eoxz0KcyJF5DK8UaVUhQaFQ==", "search"=>{"keywords"=>"", "ort"=>"A-St. Paul"}, "submit"=>"Suchen"}
(0.6ms) BEGIN
SQL (22.8ms) INSERT INTO `searches` (`keywords`, `ort`, `created_at`, `updated_at`) VALUES ('', 'A-St. Paul', '2018-06-14 15:37:58', '2018-06-14 15:37:58')
(11.1ms) COMMIT
Redirected to http://localhost:4000/searches/23
Completed 302 Found in 50ms (ActiveRecord: 34.5ms)
Started GET "/searches/23" for ::1 at 2018-06-14 17:37:58 +0200
Processing by SearchesController#show as JS
Parameters: {"id"=>"23"}
Search Load (0.7ms) SELECT `searches`.* FROM `searches` WHERE `searches`.`id` = 23 LIMIT 1
Rendering searches/show.html.erb within layouts/application
Imagecapturing Load (10.4ms) SELECT `imagecapturing`.* FROM `imagecapturing` WHERE (ort LIKE '%A-St. Paul%') ORDER BY `imagecapturing`.`id` DESC
Rendered searches/show.html.erb within layouts/application (62.5ms)
Rendered layouts/_top_nav.html.erb (6.0ms)
Imagecapturing Load (17.0ms) SELECT distinct(ort) FROM `imagecapturing` ORDER BY `imagecapturing`.`ort` ASC
Rendered searches/_links.html.erb (33.5ms)
Completed 200 OK in 409ms (Views: 340.1ms | ActiveRecord: 28.0ms)
Is in "Processing by SearchesController#show as JS" the "as JS" part the issue?
How can I get the redirect working so that after clicking the submit button it redirects to the show action?
--- UPDATE
With suggestion of user Rockwell I modified the create action to:
def create
#search= Search.create!(search_params)
respond_to do |format|
if #search
format.html {redirect_to #search}
format.json { render :show, status: :created, location: #step }
format.js { redirect_to #search }
else
format.html { render :new }
format.json { render json: #search.errors, status: :unprocessable_entity }
format.js { render :new }
end
end
end
But it still processes "as JS":
Started POST "/searches" for ::1 at 2018-06-14 18:09:18 +0200
Processing by SearchesController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D7l5ibv8hu08Z18VKqa0Y+iqGHfT+SIZTIoM8vHdcpArv8pBWszZ4Jldfcmc6LV/Wct0XaZGqnOBZXurVKaxDQ==", "search"=>{"keywords"=>"", "ort"=>"Cologny"}, "submit"=>"Suchen"}
(0.2ms) BEGIN
SQL (11.8ms) INSERT INTO `searches` (`keywords`, `ort`, `created_at`, `updated_at`) VALUES ('', 'Cologny', '2018-06-14 16:09:18', '2018-06-14 16:09:18')
(17.0ms) COMMIT
Redirected to http://localhost:4000/searches/30
Completed 302 Found in 36ms (ActiveRecord: 29.0ms)
Started GET "/searches/30" for ::1 at 2018-06-14 18:09:19 +0200
Processing by SearchesController#show as JS
Parameters: {"id"=>"30"}
Search Load (0.8ms) SELECT `searches`.* FROM `searches` WHERE `searches`.`id` = 30 LIMIT 1
Rendering searches/show.html.erb within layouts/application
Imagecapturing Load (28.1ms) SELECT `imagecapturing`.* FROM `imagecapturing` WHERE (ort LIKE '%Cologny%') ORDER BY `imagecapturing`.`id` DESC
Rendered searches/show.html.erb within layouts/application (16157.3ms)
Rendered layouts/_top_nav.html.erb (3.6ms)
Imagecapturing Load (27.6ms) SELECT distinct(ort) FROM `imagecapturing` ORDER BY `imagecapturing`.`ort` ASC
Rendered searches/_links.html.erb (39.2ms)
Completed 200 OK in 16404ms (Views: 16314.1ms | ActiveRecord: 56.5ms)
I believe that you are correct, the Processing by SearchesController#show as JS is what is causing your error. If you respond to the format it should solve your issue. I added HTML and JSON here but you wouldn't need to if you know you will never need that, just the js should be fine.
def create
#search = Search.new(search_params)
respond_to do |format|
if #search.save
format.html {redirect_to #search}
format.json { render :show, status: :created, location: #step }
format.js { redirect_to #search }
else
format.html { render :new }
format.json { render json: #search.errors, status: :unprocessable_entity }
format.js { render :new }
end
end
end
If you are sending this as an AJAX you could specify the type that gets sent as well, but I would need to see the JS code for that to give a solution to fix that.
it is working as expected, you can see it on the log, the insert is done and then the redirect too.
but the problem is the format you are asking. it seems like the create is called as js Processing by SearchesController#create as JS (maybe you are doing an ajax request with that format or your form has remote:true). and then the redirect isn't done visually of course. you need to make the create request without js format or don't make the redirect on the controller and create a "create.js" view that does the redirect. but of course it's not the best solution.
if you want to do the redirect, the best way is to change the format of the create request.
I have read countless SO questions about this issue, and can not find a solution.
I have a button that updates Meeting here:
<%= form_for(meeting) do |f| %>
<%= f.hidden_field :accepted, value: true %>
<%= button_tag(type: 'submit', class: "btn_primary") do %>
Accept <svg><use xlink:href="#checkmark"/></svg>
<% end %>
<% end %>
I get an unknown format error, BUT it still updates. What is causing this error?
I have tried removing respond_to do |format| from the update method. which solves the problem for this one button, but then breaks all the other buttons on the platform that calls meetings/update.
class MeetingsController < ApplicationController
respond_to :json, :html
def update
respond_to do |format| **error highlights this line**
if #meeting.update(meeting_params)
format.json { render :show, status: :ok, location: #meeting }
else
format.html { render :edit }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
end
Console:
Started PATCH "/meetings/224" for 127.0.0.1 at 2016-11-11 16:05:27 -0500
Processing by MeetingsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hK6AoOZuw9DWyKUXw1dXWOSUolooWgBUPnkItUJX5Tm7XvimsHd9518pkqwVvNhUi3L3vlA4OZaJZiAgrbS0Ig==", "meeting"=>{"accepted"=>"true"}, "button"=>"", "id"=>"224"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Meeting Load (0.2ms) SELECT "meetings".* FROM "meetings" WHERE "meetings"."id" = ? LIMIT 1 [["id", 224]]
(0.3ms) begin transaction
SQL (0.5ms) UPDATE "meetings" SET "accepted" = ?, "updated_at" = ? WHERE "meetings"."id" = ? [["accepted", "t"], ["updated_at", "2016-11-11 21:05:27.882521"], ["id", 224]]
(1.3ms) commit transaction
Completed 406 Not Acceptable in 24ms (ActiveRecord: 2.7ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/meetings_controller.rb:65:in `update'
This was never an issue, and seemingly came out of no where. What is the cause of this error? Thanks!
I think I know what the issue is. I've added a line to your update method
class MeetingsController < ApplicationController
respond_to :json, :html
def update
respond_to do |format| **error highlights this line**
if #meeting.update(meeting_params)
format.html { redirect_to some_rails_path }
format.json { render :show, status: :ok, location: #meeting }
else
format.html { render :edit }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
end
The reason you're getting an unknown format error but still successfully updating meeting is because your method has solid logic, so it's updating the meeting, but then once it does that, and you're only telling it what to do in terms of JSON but not in terms of HTML, you address both in your else statement, but not if the update succeeds.
Is this supposed to be an ajax request? It doesn't seem to be. But you're rendering json instead of html. If you're going to allow the page to reload you need to add an html option to if #meeting.update(meeting_params)
Something like: format.html { redirect_to #meeting, notice: 'Meeting was successfully updated.' }
If you're doing an ajax request this isn't the correct answer, but I don't see any indication in your question that you are. Lmk if you need further clarification.
I'm having trouble getting Best In Place to update. This is the first time I've used this gem or made a Rails app so I'm sure I'm just missing something simple even though I've scoured the documentation and searched through other questions here.
This is the error I get in the console:
Started PUT "/tasks/1" for 127.0.0.1 at 2016-04-22 11:52:10 -0600
Processing by TasksController#update as JSON
Parameters: {"authenticity_token"=>"cAwRbx8JeYDMG1LrR7nl0VQfwW/x00RUd8rsTP8Iwc
0=", "tasks"=>{"title"=>"Task 1sadsads"}, "id"=>"1"}
Task Load (0.0ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? ORD
ER BY priority ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? ORDER B
Y priority ASC LIMIT 1 [["id", "1"]]
Completed 400 Bad Request in 3ms
ActionController::ParameterMissing (param is missing or the value is empty: task
):
app/controllers/tasks_controller.rb:99:in `task_params'
app/controllers/tasks_controller.rb:62:in `update'
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.1.8
/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.1.8
/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.1.8
/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb
(0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.1.8
/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb (36.0ms)
My controller:
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
# GET /tasks
# GET /tasks.json
def index
#tasks = Task.all
respond_to do |type|
type.html
type.json {render :json => #task}
end
end
# GET /tasks/1
# GET /tasks/1.json
def show
#task = Task.find params[:id]
respond_to do |format|
format.html
format.json {render :json => #task}
end
end
# GET /tasks/new
def new
#task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks
# POST /tasks.json
def create
#task = Task.new(task_params)
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def sort
params[:order].each do |key,value|
Task.find(value[:id]).update_attribute(:priority,value[:position])
end
render :nothing => true
end
# PATCH/PUT /tasks/1
# PATCH/PUT /tasks/1.json
def update
#task = Task.find params[:id]
if #task.update(task_params)
respond_to do |format|
format.html { redirect_to( #task )}
format.json { render :json => #task }
end
else
respond_to do |format|
format.html { render :action => :edit } # edit.html.erb
format.json { render :nothing => true }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def task_params
params.require(:task).permit(:title, :description, :priority)
end
end
My view partial:
<div class="panel panel-default" data-id="<%= task.id %>">
<div class="panel-heading">
<h3 class="panel-title"><span class="rest-in-place" data-url="/tasks/<%= task.id %>" data-object="tasks" data-attribute="title" data-placeholder="Enter a title">
<%= task.title %>
</span></h3>
</div>
<div class="panel-body">
<%= truncate task.description, length: 50 %>
</div>
</div>
I really appreciate any help I can get. I'm 99% sure it's something I configured wrong in the controller, I just can't for the life of me figure out what it is.
EDIT: The background for this is that I have a bunch of 'Tasks' and I want to list them all on the index and be able to update any task on the index just by clicking on the title.
ActionController::ParameterMissing (param is missing or the value is empty: task
):
app/controllers/tasks_controller.rb:99:in `task_params'
app/controllers/tasks_controller.rb:62:in `update'
This is telling you that there is no parameter with the name of :task. You can see your parameters above this message.
Parameters: {"authenticity_token"=>"cAwRbx8JeYDMG1LrR7nl0VQfwW/x00RUd8rsTP8Iwc
0=", "tasks"=>{"title"=>"Task 1sadsads"}, "id"=>"1"}
You have tasks in your params here. This information is coming from your view.
data-object="tasks"
Try changing this piece in your view to task and it should send the request correctly.
I found several topics related , but couldn't figure out how to solve this problem,
This is my code
<%= f.label :projeto %><br>
<%= f.collection_select :projeto, Projeto.order(:id), :id, :name, include_blank: true %>
model => task belongs_to projeto and projeto has_many tasks
Full Error:
ActiveRecord::AssociationTypeMismatch at /tasks/1
Projeto(#69996814678740) expected, got String(#69996762580840)
Database is set to t.references.
Task_controller
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def task_params
params.require(:task).permit(:seq, :descr, :seqpai, :typo, :hour, :projeto)
end
Started PATCH "/tasks/1" for 127.0.0.1 at 2015-06-18 14:30:23 -0300
Processing by TasksController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Is7YTC0v5OONEEsIgOvmI+CEuVYG/WsoKWzskGippD2eOwthKVHb2dI+S19GkkI9aU0IwTrzwERlLq2ybWbGxw==", "task"=>{"seq"=>"0", "descr"=>"Projeto", "seqpai"=>"", "typo"=>"Analitica", "hour"=>"12", "projeto"=>"1"}, "commit"=>"Update Task", "id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT 1 [["id", 1]]
(0.2ms) begin transaction
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 25ms (ActiveRecord: 0.8ms)
Normally this is caused by assigning a string to something expecting a model association. For example:
# Not allowed, `project=` expects a Project model
#task.project = params[:project_id]
# Converts parameter into model, but may throw exception
#task.project = Project.find(params[:project_id])
# Direct assignment, requires validation on model level
#task.project_id = params[:project_id]
I changed the View for
<%= f.label :projeto_id %>
and permited in controller projeto_id
Then worked Fine,
Thanks everyone for the hint.
I have a namespace called "backend" which is protected by Devise.
I would like now to allow users to edit their profil.
So I created a users_controller in Backend.
Here's the users_controllercode :
class Backend::UsersController < ApplicationController
layout 'admin'
before_filter :authenticate_user!
def index
#users = Backend::User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
def show
#user = Backend::User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
end
def edit
#user = Backend::User.find(params[:id])
end
def update
#user = Backend::User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'Article was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
end
When I go on backend_users_path there is a list of all the users. I would like to permit to edit only his own profil.
So I go on the Edit page : <%= link_to "Edit", edit_backend_user_path(backend_user.id) %> .
Here's the Edit page code :
<%= simple_form_for #user do |f| %>
<div><%= f.label :email %><br />
<%= f.input :email, :autofocus => true %></div>
<div><%= f.submit "Update" %></div>
<% end %>
And there is my problem : when I try to modify the email address, nothing happen. The update fails.
How can I do this ?
I'm quite lost.
Thanks by advance.
Here's the log file :
Started PUT "/backend/users/1" for 127.0.0.1 at 2012-11-13 12:13:51 +0100
Processing by Backend::UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"wWrUDh7LVWhP+P7OWO6laDWaCKInxk37AA2BPuQWAI4=", "backend_user"=>{"email"=>"grellazzi#laposte.net"}, "commit"=>"Update", "id"=>"1"}
[1m[35mBackend::User Load (0.0ms)[0m SELECT `backend_users`.* FROM `backend_users` WHERE `backend_users`.`id` = 1 LIMIT 1
[1m[36mBackend::User Load (0.0ms)[0m [1mSELECT `backend_users`.* FROM `backend_users` WHERE `backend_users`.`id` = ? LIMIT 1[0m [["id", "1"]]
[1m[35mSQL (1.0ms)[0m BEGIN
[1m[36m (0.0ms)[0m [1mCOMMIT[0m
Redirected to http://localhost:3000/backend/users/1
Completed 302 Found in 23ms (ActiveRecord: 1.0ms)
Started GET "/backend/users/1" for 127.0.0.1 at 2012-11-13 12:13:51 +0100
Processing by Backend::UsersController#show as HTML
Parameters: {"id"=>"1"}
[1m[35mBackend::User Load (0.0ms)[0m SELECT `backend_users`.* FROM `backend_users` WHERE `backend_users`.`id` = 1 LIMIT 1
[1m[36mBackend::User Load (0.0ms)[0m [1mSELECT `backend_users`.* FROM `backend_users` WHERE `backend_users`.`id` = ? LIMIT 1[0m [["id", "1"]]
Rendered backend/users/show.html.erb within layouts/admin (0.0ms)
Completed 200 OK in 7ms (Views: 5.0ms | ActiveRecord: 0.0ms)
Thanks for your links, I tried to modify my user_controller with
if params[:user][:password].blank?
params[:user].delete("password")
params[:user].delete("password_confirmation")
end
#user = User.find(current_user.id)
if #user.update_attributes(params[:user])
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to root_path
else
render "edit"
end
But it fails...
If nothing happens, that usually indicates a validation error, in your case probably a missing password or other data that is not part of your form but is still being validated. To debug this, output #user.errors.inspect to your logfile or look at error_messages_on #user in your view.
In general, take a look at these guides on how to allow users to edit their (partial) profile:
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password