I am trying to create nested routes for a project that has many boards.
First I am creating a link to a new board:
<%= link_to 'New Board', new_project_board_path(#project) %>
In routes.rb I just nested the restful routes:
resources :projects do
resources :boards
end
And in the boards controller I adapted the new and create action as follows:
def new
#project = Project.find(params[:project_id])
#board = #project.boards.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #board }
end
end
def create
#project = Project.find(params[:project_id])
#board = #project.boards.new(params[:board])
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
At least I also changed the _form.html.erb into:
<%= form_for([#project, #board]) do |f| %>
etc.
My problem starts when I click the button create board (so the new action is executed) it says no route matches. I guess it has to do with the create action because it doesn't get the id of the project anymore? I really don't know what else to change and where.
Seems your error is here
format.html { redirect_to #board, notice: 'Board was successfully created.' }
You don't have non-nested :boards resources, do you? Try to change this line to
format.html { redirect_to [#project, #board], notice: 'Board was successfully created.' }
Related
I am getting error - undefined method collect for nil:NilClass, but I am able to render option list from another database table, and also able to save data in stage table but not able to update it.
I am rendering option list form responsibility table in stage form field responsibility option and saves that option into stage table.
stages_controller.rb
def index
redirect_to project_path(#project)
end
def show
end
def new
#stage = Stage.new
#responsibilities = #project.responsibilities
end
def edit
end
def create
#responsibilities = #project.responsibilities
#stage = #project.stages.build(stage_params)
respond_to do |format|
if #stage.save
format.html { redirect_to project_path(#project), notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def update
#responsibilities = #project.responsibilities
respond_to do |format|
if #stage.update(stage_params)
format.html { redirect_to project_stages_url, notice: 'Stage was successfully updated.' }
format.json { render :show, status: :ok, location: #stage }
else
format.html { render :edit }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def destroy
#stage.destroy
respond_to do |format|
format.html { redirect_to project_stages_url, notice: 'Stage was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_stage
#stage = Stage.find(params[:id])
end
def find_project
#project = Project.find(params[:project_id])
end
your edit method is empty, so #responsibility has no content (null), you can put some code for example (from your other method)
def edit
#project = Project.find(params[:id])
#responsibilities = #project.responsibilities
...
end
The issue here is that #responsibilities is not defined in your partial.
You should pass the local variable to the partial like this -
<%= render partial: "form", locals: {responsibilities: # responsibilities} %>
and then you can use responsibilities inside the form partial
More about passing variable to partials
I'm building an app like reddit where you add a Submission to a specific user page. Submission has a few attribute including an attribute called url.
I want to check when adding a new submission if already a submission with that same url exists for that specific page, and if it exist, vote for it instead of creating it as a new submission. If not, just add it as a new submission. I'm using the act_as_votable gem here.
Here is the create method:
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.new(submission_params)
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
you should take a look at https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by and https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_initialize_by
Now on your code we can make changes like
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.find_or_initialize_by(submission_params)
if #submission.id.present?
# What to do if the record exists
else
# if its a new record
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
end
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I hope that this can put you on the right track
Happy Coding
I am trying to change the redirect when I create a listing, but I keep getting a No route matches {:action=>"manage_photos", :controller=>"listings"} missing required keys: [:id]. What am I missing? My route is nested and there is a manage_photos method in my controller. Not sure where to go from here.
routes.rb
resources :listings do
member do
get 'like'
get 'unlike'
get 'duplicate'
get 'gallery'
delete 'gallery' => 'listings#clear_gallery'
get 'manage_photos'
get 'craigslist'
get "add_to_collection"
get 'request_photos'
get 'rsvp'
end
end
rake routes:
manage_photos_listing GET /listings/:id/manage_photos(.:format) listings#manage_photos
listings_controller:
create method:
def create
#listing = Listing.new(listing_params)
respond_to do |format|
if #listing.save
format.html { redirect_to manage_photos_listing_path, notice: 'Listing was successfully created.' }
format.json { render json: #listing, status: :created, location: #listing }
else
format.html { render action: "new", notice: "Correct the mistakes below to create the new listing" }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
manage_photos method:
def manage_photos
#listing = Listing.find(params[:id])
end
error:
Since it is a nested resource you have to add the id of the parent element. Try:
manage_photo_listing(#listing)
so it can actually use the id of #listing and build the route
I'm building a site where a link to fill a new form can be clicked from an Event show page
<%= link_to 'Be a Contestant', new_form_path(:event_id => #event.id)%>
This creates a link like
http://localhost:3000/forms/new?event_id=2
Now if the form is filled with an error, when submitted, it returns an error
Couldn't find Event with 'id'=""
So I decided to use the request.referrer to redirect back to the previous page but it doesn't list the errors as use this method
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to request.referrer }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
I also tried this but to no avail.
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to new_form_path(:event_id => request.referrer.params[:event_id]) }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
What you probably really need to do is to add a hidden field event_id to the form because I'm betting that event_id doesn't get propagated from the #new to the #create action.
See here for more information on hidden_field_tag
You usually just render the edit view when there was an error in create:
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { render :edit, alert: 'Error creating ...' }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
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.