I am getting a "No route matches [POST]" when submitting a new form.
### /routes.rb ###
resources :artists, controller: 'artists/artists', only: [:show] do
member do
resources :videos, controller: 'artists/videos', only: [:index, :new, :create, :edit, :update]
end
end
### /artists/videos/videos_controller.rb ###
class Artists::VideosController < ApplicationController
before_action :set_artist
def new
#video = ArtistVideo.new
end
def create
#video = #artist.create_artist_video(video_params)
if #video.save
redirect_to current_artist
else
render 'new'
end
end
private
def set_artist
#artist = current_artist
end
end
### /artists/videos/new.html.erb ###
<%= form_for(#video, url: new_video_path) do |f| %>
<%= f.label :video_title, "title", class: "label" %>
<%= f.text_field :video_title, class: "text-field" %>
<%= f.label :video_description, "decription", class: "label" %>
<%= f.text_field :video_description, class: "text-field" %>
<%= f.label :youtube_video_url, "youtube url", class: "label" %>
<%= f.text_field :youtube_video_url, class: "text-field" %>
<%= f.submit "add video", class: "submit-button" %>
<% end %>
### rake routes ###
videos_path GET /artists/:id/videos(.:format) artists/videos#index
POST /artists/:id/videos(.:format) artists/videos#create
new_video_path GET /artists/:id/videos/new(.:format) artists/videos#new
edit_video_path GET /artists/:id/videos/:id/edit(.:format) artists/videos#edit
video_path PATCH /artists/:id/videos/:id(.:format) artists/videos#update
PUT /artists/:id/videos/:id(.:format) artists/videos#update
So not sure what I'm doing wrong here. I've tried taking :index completely out so videos_path uses the post method, but I still have the same problem.
I'm using the has_many method linking videos to artists, if that even matters.
Not sure if it's the routs or the controller code that's wrong. Any help would be appreciated.
You're specifying a path url: new_video_path but that is for videos#new and what you want is the create path, which is a post to videos_path(#artist). Since it's a nested resource, the path has to have the artist_id which it can get from the #artist instance.
But, the simpler way to do this is like so:
form_for[#artist, #video] do |f|
Related
I'm trying to make a dropdown search by category feature on my webapp. I am currently trying to get the dropdown menu to work, but I am constantly getting the error saying:
First argument in form cannot contain nil or be empty
Here is the view:
<%= form_for #search, html: {class: "pure-form"} do |s| %>
<div class="field">
<%= s.label :category %>
<%= s.select(:category, options_for_select([['Other', 'Other'], ["Breakfast", "Breakfast"], ["Lunch/Dinner", "Lunch/Dinner"], ["Dessert", "Dessert"]])) %>
<%end%>
<div class="card-columns">
<% #images.each do |image| %>
<div class="card">
<div class="card-body p-1">
<%= image_tag image.image, class: 'd-block w-100' %>
<%= link_to image.title, image_path(image.id), class: "btn btn-primary stretched-link" %>
</div>
</div>
<% end %>
</div>
And here is the controller:
class SearchesController < ApplicationController
def new
#search = Search.new
#categories = Image.uniq.pluck(:category)
end
def create
#search = Search.create(search_params)
redirect_to #search
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit(:category)
end
end
And here are the routes:
Rails.application.routes.draw do
devise_for :users
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root 'pages#home'
get '/images', controller: 'images', action: 'recent'
get '/upload', controller: 'images', action: 'new'
get '/#:username', to: 'users#show', as: :profile
delete 'images/:id(.:format)', :to => 'images#destroy'
resources :images, only: [:index, :show, :create]
get 'searches/search'
resources :searches
end
I tried to configure different things to see if I could get it working, but I could not. I am very unclear as to what is the problem. Any help would be appreciated! Thanks in advance!
In my views I have a form and trying to update quantity for an order line:
<div class="quantity">Quantity</br>
<%= form_tag(order_line_path(line.id), method: "patch") do %>
<%= number_field_tag 'qty', '1', within: 1...line.book.stock %>
<%= submit_tag "Update", class: "btn btn-primary" %>
<% end %>
</div>
The instance variable in the rest of my view is a collection of order lines, so I cannot use it.
Then I have in my controller the update method:
def update
#order = current_order
#order_line = #order.order_lines.find(params[:id])
#order_line.update_attributes(order_line_params)
end
And my strong params definition:
def order_line_params
params.require(:order_line).permit(:qty)
end
I get this error :
param is missing or the value is empty: order_line
Could someone please have a look?
Thanks!
The reason you are getting param is missing or the value is empty: order_line is that you are using form_tag which gives a "flat" params hash.
However this is easily avoidable if you just use form_with/form_for.
# routes.rb
resources :orders do
resources :line_items, shallow: true
end
# app/views/order_items/edit.html.erb
# use `form_with(model: #order_item)` in Rails 5
<%= form_for(#order_item) do |f| %>
<%= f.label :qty, within: 1...f.object.book.stock %>
<%= f.number_field :qty, %>
<%= f.submit %>
<% end %>
class OrderItemsController < ApplicationController
before_action :set_order_item, only: [:show, :edit, :update, :destroy]
# ...
# GET /order_items/:id/edit
def edit
end
# PATCH /order_items/:id
def update
if #order_item.update(order_item_params)
redirect_to #order_item, notice: 'Line updated'
else
render :edit
end
end
private
def set_order_item
#order_item = OrderItem.find(params[:id])
end
def order_item_params
params.require(:order_item).permit(:qty)
end
end
But what you're really looking for unless you are doing the update/creation of nested items with AJAX is most likely a combination of accepts_nested_attributes and fields_for which will let the user mass edit the line items:
class Order < ApplicationRecord
accepts_nested_attributes_for :order_items
end
<%= form_for(#order) do |f| %>
<%= fields_for(:order_items) do |oif| %>
<%= f.label :qty, within: 1...f.object.book.stock %>
<%= f.number_field :qty, %>
<% end %>
<%= f.submit %>
<% end %>
class OrdersController < ApplicationController
# PATCH /orders/:id
def update
if #order.update(order_params)
redirect_to #order, notice: 'Order updated.'
else
render :new
end
end
private
def order_params
params.require(:order).permit(order_items_attributes: [:qty])
end
end
I have a Job model that contains a Company_id as a foreign key. On the Job new page, I want to create a new job using simple form like this
<%= simple_form_for (#job) do |f| %>
<%= f.input :title, label: "Title of job" %>
<%= f.submit 'Create', class: "btn btn-success" %>
<% end %>
This is my nested route
resources :companies do
resources :jobs, only: [:show, :new, :create, :update, :destroy]
end
In my jobs controller new and create method, I have
def new
#job = Job.new
end
def create
#job = Job.new(job_params)
#company = params[:company_id]
#job.company_id = #company
if #job.save
redirect_to company_job_path
else
render :new
end
end
This is the route to the job show page
company_job GET /companies/:company_id/jobs/:id(.:format) jobs#show
and the job create page
company_jobs POST /companies/:company_id/jobs(.:format) jobs#create
I keep getting the error below when I try to create a job using simple form.
No route matches [POST] "/jobs"
Any help would be appreciated.
Just add <%= simple_form_for [#company, #job] do |f| %> instead of <%= simple_form_for (#job) do |f| %> I suppose you have #company set when form is rendered.
According your nested routes you need to set company before jobs
so either use before action set company of find company before use this
in controller
before_action :set_company
def new
##company = Company.find(params[:company_id])
#job = #company.jobs.new
end
private
def set_company
#company = Company.find(params[:company_id])
end
in view pass full url
<%= simple_form_for #job, :url => company_jobs_path(#company, #job), :method => :post%>
<%= f.input :title, label: "Title of job" %>
<%= f.submit 'Create', class: "btn btn-success" %>
<% end %>
Hello guys I am developing an application in ruby on rails I am trying save the contents of a form through ajax
Here is the code of my form :
<%= form_for([#question, #question.answers.build],remote: true) do|f|%>
<h2>Link</h2>
<%= f.text_field :link ,:id=>'link'%>
<h2>Time</h2>
<p class="s-line">
<%= f.label :hh,"HH:" %>
<%= f.text_field :hh ,:id=>'hh'%>
<%= f.label :mm,"MM:" %>
<%= f.text_field :mm,:id=>'mm' %>
<%= f.label :ss,"SS:"%>
<%= f.text_field :ss,:id=>'ss' %>
<%= f.hidden_field :user,:value =>session[:username] %>
</p>
<%= f.submit "Answer" ,:class=>'btn btn-medium btn-success'%>
<% end %>
and the code of controller is :
def create
question = Question.find(params[:question_id])
#answer = question.answers.create(ans_params)
respond_to do |create|
create.js{}
end
end
an I was getting this error :
ActionController::InvalidAuthenticityToken
And I tried to solve this by putting this line
skip_before_action :verify_authenticity_token
to my controller.
now I am getting this error
ActionController::UnknownFormat
In this line
respond_to do |create|
Please help
I think the solution lies here:
<%= form_for([#question, #question.answers.build],remote: true) do|f|%>
Question
Why are you sending #question.answers.build with the #question var? IMO this is bad practice, and I'd do this:
<%= form_for #answer, remote: true do |f| %>
#config/routes.rb
resources :questions do
resources :answers, only: [:new, :create]
end
#app/controllers/answers_controller.rb
respond_to :html, :js: json
before_action :find_question, only: [:new, :create]
def new
#answer = #question.answers.build
end
def create
#answer = #question.answer.create(ans_params)
end
private
def find_question
#question = Question.find(params[:question_id])
end
def ans_params
params.require(:answer).permit(:attrs)
end
For your Ajax authentication issue - I believe it is a problem with how you're declaring & handling the data in your form. I would try the refactors I posted above & see if that helps
Routes
resources :locations, :only => [:new, :create]
Controller
class LocationsController < ApplicationController
def new
#location = Location.new
end
def create
#location = Location.new(location_params)
if #location.save
flash[:notice] = 'Created location successfully'
redirect_to new_location_path
else
flash[:notice] = 'Invalid information. Please try again'
render :new
end
end
private
def location_params
params.require(:location).permit(:name, :street, :city, :state)
end
end
Error message when I click save.
ActionController::RoutingError:
No route matches [POST] "/locations/new"
view
<%= simple_form_for :locations do |form| %>
<%= form.input :name %>
<%= form.input :street %>
<%= form.input :city %>
<%= form.input :state %>
<%= form.submit 'Create location' %>
<% end %>
Using capybara to test that when I click on save it creates a new location. I'm not quite sure why it doesn't know what the post route is because I have the new and create routes. If I put a binding.pry right underneath the create method it doesn't get called. So my create method is not being called for some reason.
EDIT:
Rake Routes
locations POST /locations(.:format) locations#
new_location GET /locations/new(.:format) locations#new
A resource normally GETs to new and POSTs to create. So your form is probably submitting back to the new actions instead of submitting to the create action.
Here's the guide for this: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
The problem was in the views.
<%= simple_form_for :locations do |form| %>
<%= form.input :name %>
<%= form.input :street %>
<%= form.input :city %>
<%= form.input :state %>
<%= form.submit 'Create location' %>
<% end %>
I was calling on locations symbol when I should have been calling on the instance variable #location from the controller.
The actual problem was that rails 3.2.12 doesn't take private params
Using resources, the new action should be fetched with GET instead of POST. create will be POST. Check your rake routes