I'm building a simple online shop for practice and want to track order histories, at the moment I'm getting the user to submit but the shipping address and order history, later I'll upgrade order history to be a hidden field.
The problem is that I can't get the simple form to submit anything to my database.
My form looks like this:
<p class="text-center">
congratulations your order is almost complete, please fill out the form below to place your order or <%= link_to "browse other products.", root_path %>
</p>
<%= simple_form_for #placeorder, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<div class="form-inputs" >
<%= f.input :shipping_address, label: false, placeholder: 'Shipping address', input_html: { class: 'input-lg', required: true } %>
<%= f.input :order_history, label: false, placeholder: 'order_history', input_html: { class: 'input-lg', required: true } %>
</div>
<div class="form-actions">
<%= f.button :submit, "Confirm order" %>
</div>
<% end %>
My place order controller looks like this:
class PlaceOrdersController < ApplicationController
def new
current_order.order_items.each do |order_item|
#last_item_name = order_item.product.name
end
#placeorder = PlaceOrder.new
#order = current_order.order_items
end
def create
#placeorder = PlaceOrder.create(place_order_params)
p "HELLO #{#placeorder}"
if #placeorder.save
flash[:success] = "You've made your order"
redirect_to root_path
else
flash[:alert] = "Something went wrong, check the form and submit your order again"
render :new
end
end
private
def place_order_params
params.require(:place_order).permit(:shipping_address, :order_history)
end
end
My routes.rb looks like this:
Rails.application.routes.draw do
resources :products
resources :checkout
resources :place_orders
resource :cart, only: [:show]
resources :order_items, only: [:create, :update, :destroy], defaults: { format: 'js' }
root to: "products#index"
devise_for :users, :controllers => { registrations: 'registrations' }
end
I have other forms that are working fine and they look the same. Any help would be greatly appreciated.
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!
View/Form
<div class="col-lg-12">
<div class="ibox-content">
<div class="row">
<%= simple_form_for supplier_fuel_prices_path(#supplier,#fuel_price), method: :post do |f| %>
<%= f.input :regular, label: "Regular" %>
<%= f.input :medium, label: "Medium"%>
<%= f.input :premium, label: "Premium" %>
<%= f.input :diesel, label: "Diesel" %>
<%= f.button :submit, "Update"%>
<%end%>
</div>
</div>
</div>
</div>
</div>
controller
class Supplier::FuelPricesController < Supplier::ApplicationController
before_action :set_supplier
def index
end
def new
#fuel_price = #supplier.fuel_prices.build
end
def create
#fuel_price = #supplier.fuel_price.build(fuel_price_params)
if #fuel_price.save
flash[:notice] = "You have successfully Added new Fuel Price."
redirect_to supplier_fuel_prices_path
else
flash.now[:alert] = "Something went wrong. Please try again."
render "new"
end
end
private
def fuel_price_params
params.require(:fuel_price).permit(:regular, :medium, :premium, :diesel)
end
def set_supplier
#supplier = User.find_by(params[:supplier_id])
end
end
Models
User model has has_many :fuel_prices, foreign_key: :supplier_id
Fuel Price Model has belongs_to "supplier", class_name: "User"
Error i am getting when submitting the form is
No route matches [POST] "/supplier/fuel_prices/new"
My routes looks like this
namespace :supplier do
root to: 'dashboard#index', as: 'dashboard'
resources :retailers
resources :fuel_prices
end
Routes
supplier_fuel_prices_path GET /supplier/fuel_prices(.:format)
POST /supplier/fuel_prices(.:format) supplier/fuel_prices#create
new_supplier_fuel_price_path GET /supplier/fuel_prices/new(.:format) supplier/fuel_prices#new
edit_supplier_fuel_price_path GET /supplier/fuel_prices/:id/edit(.:format) supplier/fuel_prices#edit
supplier_fuel_price_path
You're just trying to post to the wrong path. A url ending in new is typically going to be a get request. Run rake routes and make sure you're posting to the correct post route and update your form.
I am very new to rails and am attempting to get some practice by building a profile page. I have implemented devise and once a user has signed in they can click on a link that displays a profile with information about them. Right now it is just displaying their name, date of birth, and gender. I would like for it to also display an image of them. So I have bundled the paperclip gem and read through some tutorials to try and get it configured. I have gotten the code in place, so that a user can click on 'choose file' and select an image. However when I click 'update' it provides me with an error. I'd like for the image to display on the same show page of their profile.
profiles_controller.rb
class Users::ProfilesController < ApplicationController
def edit
#profile = Profile.create(params[:photo])
end
def create
end
private
def profile_params
params.require(:profile).permit(:photo)
end
end
profiles/edit.html.erb
<h2>Edit Account Profile </h2>
<%= form_for(#profile, url: profiles_edit_path(#profile), html: { :multipart => true }) do |f| %>
<li>
<%= f.label :photo, "Photo" %>
<%= f.file_field :photo %>
</li>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<%= link_to "Back", :back %>
registrations/show.html.erb
<%= image_tag #profile.photo.url %>
<br>
<%= #user.email %>
<br>
<%= #user.first_name %>
<%= #user.last_name %>
<br>
<%= #user.date_of_birth %>
<br>
<%= #user.is_female %>
registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def show
#user = User.find(params[:id])
end
private
def sign_up_params
params.require(:user).permit(:first_name, :last_name, :is_female, :date_of_birth, :email, :password, :password_confirmation)
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :is_female, :date_of_birth, :email, :password, :password_confirmation, :current_password)
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :registrations => 'users/registrations', :profiles => 'users/profiles' }
devise_scope :user do
get 'profiles/edit' => 'users/profiles#edit'
post 'profiles/edit' => 'users/profiles#edit'
get 'users/:id' => 'users/registrations#show', as: :user
end
root to: "home#index"
end
Error after clicking update:
Routing Error
No route matches [PATCH] "/profiles/edit.21"
I appreciate any assistance, and please let me know if any further information is needed.
Try:
patch 'profiles/:id' => 'users/profiles#update'
and form helper should like this:
<%= form_for(#profile, html: { :multipart => true }) do |f| %>
Hope it is helpful for you!!
try adding this route to devise_scope to pass that error
patch 'profiles/edit' => 'users/profiles#edit'
btw, in ProfilesController
creating new Profile should be in create action
in edit action, you should load existed profile and render edit view
Update:
form in edit view will submit data to action update, we need get profile again and update data for it
your routes is not correct, when edit a profile, we should submit to a url look like users/profiles/4/update
you can declare routes as below
devise_for :users, :controllers => { :registrations => 'users/registrations' }
namespace :users do
resources :profiles
end
In update action, you retrieve that profile p = Profile.find(params[:id]) and update it p.photo = params[:photo]; p.save or anything you want
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|
I'm trying to implement the 'Wicked' gem for wizards and cannot figure out this error for the life of me. Already referenced Ryan bates railscast #346 and the step by step tutorial by schneems.
I have 2 controllers: Weddings and Wedding_steps. The user initially creates a Wedding and after the create action is redirected to the Wedding_steps controller (which uses Wicked) to update the wedding model with additional info.
The wedding_id is successfully detected in the first step weddingdetails, but after submitting that step, I get the following error:
ERROR
ActiveRecord::RecordNotFound in WeddingStepsController#update
Couldn't find Wedding without an ID:
app/controllers/wedding_steps_controller.rb:11:in `update'
Parameters:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"JMd+8gf4rVqOSNMSFrKcD3WxK+X3zvYliSMWqTg0SkE=",
"wedding"=>{"bridename"=>"",
"groomname"=>"",
"weddingdate"=>"",
"weddingcity"=>"",
"weddingstate"=>"",
"url"=>""},
"commit"=>"Next",
"id"=>"wedding_id=11"}
It is supposed to continue to the next step /wedding_steps/eventdetails?wedding_id=11 but instead gives the error and goes to /wedding_steps/wedding_id=11
Also of note is that without the Update action in place, the information successfully saves and redirects to the Wedding Show action.
Here is the relevant code:
wedding_steps_controller.rb
class WeddingStepsController < ApplicationController
include Wicked::Wizard
steps :weddingdetails, :eventdetails
def show
#wedding = Wedding.find(params[:wedding_id])
render_wizard
end
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(params[:wedding])
render_wizard #wedding
end
end
weddings_controller.rb
def create
#wedding = current_user.weddings.new(params[:wedding])
respond_to do |format|
if #wedding.save
format.html { redirect_to wedding_steps_path(:id => "weddingdetails", :wedding_id => #wedding.id) }
format.json { render json: #wedding, status: :created, location: #wedding }
else
format.html { render action: "new" }
format.json { render json: #wedding.errors, status: :unprocessable_entity }
end
end
end
STEP 1: wedding_steps/weddingdetails.html.erb
<%= simple_form_for(#wedding, :url => wizard_path(wedding_id: #wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="formrow center">
<%= f.input :bridename, placeholder: "The Bride's Name", label: false %>
<h2 class="inline"> &</h2>
<%= f.input :groomname, placeholder: "The Groom's Name", label: false %>
</div>
<div class="formrow center">
<%= f.text_field :weddingdate %>
<!-- OLD STYLE DATE FORMAT <%= f.input :weddingdate, label: "Wedding Date" %> -->
<%= f.input :weddingcity, label: "City" %>
<%= f.input :weddingstate, label: "State" %>
</div>
<div class="formrow center">
<%= f.input :url, placeholder: "i.e. 'johnandkate' ", label: false %>
</div>
</div>
<div class="form-actions center">
<%= f.button :submit, value: "Next" %>
</div>
<% end %>
<%= link_to 'skip', next_wizard_path(wedding_id: #wedding.id) %>
STEP 2: wedding_steps/eventdetails.html.erb
EVENT DETAILS STEP <!--PLACEHOLDER FOR NOW -->
Routes.rb
Jobshop::Application.routes.draw do
resources :pins
resources :weddings
resources :wedding_steps
get "users/show"
root :to => 'pages#home'
get 'about' => 'pages#about'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
resources :inviterequests
devise_for :views
ActiveAdmin.routes(self)
devise_for :users
ActiveAdmin.routes(self)
match 'users/:id' => 'users#show'
This line:
<%= simple_form_for(#wedding, :url => wizard_path, :method => :put, html: { class: 'form-horizontal'}) do |f| %>
Should be:
<%= simple_form_for(#wedding, :url => wizard_path(wedding_id: #wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>
Note the wizard_path(wedding_id: #wedding.id) When you submit the form you should see parameters = {:wedding_id => some_number} in the logs.
Paste the output of the params for the update action if it doesn't work.
Edit:
You should have ":wedding_id" as part of the required url this will make it impossible to even generate a link to that controller unless it has a properly formatted url.
Replace this
resources :wedding_steps
with this
scope "weddings/:wedding_id" do
resources :wedding_steps
end
So now a correct url would look like weddings/83/wedding_steps/weddingdetails. Likely one or more of your view helpers isn't including wedding_id properly and with this new constraint you will raise an error in the view, but this is a good thing since it will show you where the malformed link is.
I tried the solution provided by Schneems, however it is not running completely without errors. I implemented the following way.
Change
resources :wedding_steps
To
scope "weddings/:wedding_id" do
resources :wedding_steps
end
The problem is parameters are displayed as forbidden based on the error that has been thrown as ActiveModel::ForbiddenAttributesError
To get rid off this,
Change
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(params[:wedding])
render_wizard #wedding
end
To
def update
#wedding = Wedding.find(params[:wedding_id])
#wedding.update_attributes(wedding_params)
render_wizard #wedding
end
private
def wedding_params
params.require(:wedding).permit(........your parameters here.................)
end