change routes of update rails - ruby-on-rails

I have a doubt in changing a route value.
I have this situation:
routes.rb
patch 'supplies/update'
get 'supplies/edit'
get 'supplies/index'
views/supplies/edit.html.erb
<%= form_for #supply , :url => supplies_update_path(id: #supply) do |f| %>
....
i would use in the edit.html.erb file the following code:
<%= form_for #supply do |f| %>
what i have to change in the route to obtain the correct supply_path for this form_for?
thank you.
EDIT:
class SuppliesController < ApplicationController
before_action :set_supply, only: [:show, :edit, :update, :destroy]
load_and_authorize_resource
# GET /supplies/index
def index
#supplies = Supply.includes(:product).all
end
def edit
end
# PATCH/PUT /supplies/1
def update
respond_to do |format|
if #supply.update(supply_params)
format.html { redirect_to supplies_index_path, notice: 'Quantità Aggiornata.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #supply.errors, status: :unprocessable_entity }
end
end
end
private
def set_supply
#supply = Supply.includes(:product).find(params[:id])
rescue ActiveRecord::RecordNotFound
render :template => 'public/404.html'
end
def supply_params
params.require(:supply).permit(:quantity)
end
end

You can simply use <%= form_for #supply do |f| %> for edit.html.erb file. Reason is: When you instantiate #supply in edit method in SuppliesController, Rails will automatically post the form to update method, you do not need to tell it explicitly. Same way, in new.html.erb, you will also use the same: <%= form_for #supply do |f| %>, but now in your new method, you will do #supply = Supply.new, Rails will post this form to create method.
You do need to define routes, but as far as correct path is concerned, Rails will take care of it as long as you provide correct #supply variable in form_for.
Edit:
In your routes file:
resources :supplies

Related

How do you update an attribute with a button from a join table with another controller in rails?

I have a rails application, where I have set up a scaffold named event, users with devise and compared them in a third table UserEventStates, which makes it possible for each user to select their state for each event different (like here). In my events_controller, I have a create action which sets the status for each user to 0 (default). I can display and count the states as expected, but how can I update them through a button and how can I change the .update(state: 1) to .update(state: state) and set/specify the state in my view? I tried the following:
Edit: I found out that the error is based on the route get /update_user_event_state/:id, it should be another.. How do I find out which route I need?
#app/controllers/events_controller.rb
before_action :set_event, only: %i[ show edit update destroy update_user_event_state]
before_action :set_user_event_state, only: %i[ show update_user_event_state]
def create
#event = Event.new(event_params)
#users = User.all
respond_to do |format|
if #event.save
format.html { redirect_to event_url(#event), notice: "Termin wurde erstellt" }
format.json { render :show, status: :created, location: #event }
#users.each do |user|
UserEventState.new(user_id: user.id, event_id: #event.id, state: 0).save
end
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
def update_user_event_state
self.update(state: 1)
end
private
def set_event
#event = Event.find(params[:id])
end
def set_user_event_state
#ues_event = UserEventState.where(event_id: #event.id)
end
def event_params
params.require(:event).permit(:description, :date, :meeting_time, :start_time, :end_time)
end
#app/views/events/show.html.erb
<% #ues_event.each do |uesev| %>
<%= uesev.user.email %>
<%= uesev.state %>
<%= uesev.night %>
<%= button_to "Zusagen", update_user_event_state_path(uesev) %>
<% end %>
#config/routes.rb
devise_for :users
resources :events do
resources :users
end
get '/update_user_event_state/:id', to: 'events#update_user_event_state', as: 'update_user_event_state'
root "events#index"
get '/update_user_event_state/:id', to: 'events#update_user_event_state', as: 'update_user_event_state'
Change the above routes to have 2 parameters.
First parameter will have the event id
Second parameter will have state value(I believe its an id)
get '/update_user_event_state/:id/:state_id', to: 'events#update_user_event_state', as: 'update_user_event_state'
Now in the views add an extra parameter for the user which would pass the state_id parameter to the controller while clicking the button.
#app/views/events/show.html.erb
<% #ues_event.each do |uesev| %>
<%= uesev.user.email %>
<%= uesev.state %>
<%= uesev.night %>
<%= button_to "Zusagen", update_user_event_state_path(uesev, state_id: YOUR_STATE_ID_VALUE) %>
<% end %>
Now access this state_id parameter in the controller on update_user_event_state method like below
def update_user_event_state
self.update(state: params[:state_id])
end
Posted this answer assuming that the existing state updation workflow works perfectly.

Is it possible to make create form on Index page in rails5?

I have model Project (:title field), that has_many Todos (:text field and project_id field) . I want to have form, to create this Todos, using my projects_controller index page. I tried to do it like this:
My projects_contoller
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def update
end
def create
#todo = Todo.create(todo_params)
end
def delete
end
private
def todo_params
params.require(:todo).permit(:text, :project_id)
end
end
And my projects index.html.erb
<%= form_for #todo, url: {controller: "projects", action: "create"} do |r| %>
<%= r.text_field :text %>s
<%= r.text_field :project_id %>
<%= r.submit %>
<% end %>
But when I run my app I get an error:
First argument in form cannot contain nil or be empty
Which says, that I have some problem in
<%= form_for #todo, url: {controller: "projects", action: "create"} do |r| %>
What should I do, to make it possible? Is it even possible to perform create on index page?
First problem:
As khaled noted - If create the new object in your project index controller method.
#projects_controller.rb
def index
#todo = Todo.new
#projects = Project.all
end
The issue of redirecting to the wrong place is all in your form code.
<%= form_for #todo, url: {controller: "projects", action: "create"} do |r| %>
This is telling your form action (which you can see in the html if you inspect the form element) -to be action in the projects controller.
Replace this:
#todo, url: {controller: "projects", action: "create"}
with
#todo
strictly speaking you don't need the controller and action definition if the object has it's own path in the routing table. Then make sure the redirect from todo create goes back to the index of projects instead of the index of todos.
#todos_controller.rb
def create
#todo = Todo.new(todo_params)
respond_to do |format|
if #todo.save
format.html { redirect_to projects_path, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: #todo }
else
format.html { render :new }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
This will mean that if the request is processed successfully, it will redirect to the projects index.
If it's a json request it will render the show.json.jbuilder.
If it's an unsuccessful html request it will render the app/views/todos/new.html.erb file
This will allow to do display errors to the user and correct any issues with the POST.
All you need to add in your controller index method is:
#todo = Todo.new
In projects_controller.rb
before_action :initialize_todo, only: [:index]
private
def initialize_todo
#todo = Todo.new
end
In index.html.erb
<%= form_for #todo do |r| %>
Form will redirect to create method inside the todos_controller

undefined method `albums_path'

I dont understand why this is happening but I am getting this error.
undefined method albums_path and it says that it is on the first line in this code:
<%= form_for #album, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
<div class="control-group">
<%= f.label :name, :class => 'control-label' %>
<div class="controls">
but I dont see why. here is my controller:
class AlbumsController < ApplicationController
before_action :set_album, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#user = User.find_by_id(params[:id])
#albums = Album.all.where(:user_id => #user)
end
def show
redirect_to user_albums_url
end
def new
#album = Album.new
end
def edit
end
def create
#album = current_user.albums.new(album_params)
respond_to do |format|
if #album.save
if params[:images]
params[:images].each { |image|
#album.pictures.create(image: image)
}
end
format.html { redirect_to #album, notice: 'Gallery was successfully created.' }
format.json { render json: #album, status: :created, location: #album }
else
format.html { render action: "new" }
format.json { render json: #album.errors, status: :unprocessable_entity }
end
end
end
def update
#album.update(album_params)
redirect_to user_albums_url
end
def destroy
#album.destroy
redirect_to user_albums_url
end
private
def set_album
#album = Album.find(params[:id])
end
def album_params
params.require(:album).permit(:name, :description, :images)
end
end
and my routes are as follows:
resources :users do
resources :albums do
resources :pictures do
resources :comments
end
end
end
Ive looked everywhere for my code even mentioning "albums_path" but it doesnt say it anywhere. Is there anything that you guys can think of being the problem? I've tried fixing the forms but it doesnt seem to work. another thing that you might want to see is the link to new action. here it is:
<%= link_to 'New Album', new_user_album_path(:user_id => current_user.id), :class => 'btn btn-mini' %>
I don't know if this helps at all but I'm using the paperclip gem to create albums.
Your albums resource is nested within users resource. Therefore you should set user in your new action (or, better, in before_filter):
before_filter :set_user
# ...
def set_user
#user = User.find(params[:user_id])
end
and add user reference to your form:
form_for [#user, #album] do |f|
BTW, instead of #albums = Album.all.where(:user_id => #user), you can have (it's much more idiomatic in Rails): #albums = #user.albums.

simple_form undefined method `model_name' for NilClass:Class

I'm learning Rails, and I would like to use simple_form.
I'm creating a simple app (my first one), and I want to create a signup form.
I used rails g scaffold User username:string password:string to create my model and controller.
I'm using Foundation gem too, if that's matter, and I install simple_form with the right command for Foundation.
I've been looking for answers for two hours, I tried many things, I have no idea of what's wrong with my code.
## app/views/home/index.html.erb ##
<%= simple_form_for #User do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<% end %>
## app/models/user.rb ##
class User < ActiveRecord::Base
end
## app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User 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
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:username, :password)
end
end
I'm obviously doing something wrong, and I'm pretty sure I will feel like an idiot, but it's my first app :/
Thanks you.
EDIT: I forgot to say, I tried (desperately) every vars (#user, #users, #User, #Users), any of them doesn't works :/
Get rid of the form from the index.html.erb view (and no, don't put it in show.html.erb either!).
Place this form in the new.html.erb view:
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.submit %>
<% end %>
Note that the form should reference #user not #User.
Yep ... in the view you are using the #User instance variable (with uppercase U) but in the controller you assign the model to the #user instance variable (with lowecase u) :)
Put #user in lowcase (not #user)
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<% end %>
And save it as new.html.erb view not index.html.erb!

Rails 4.0 ActiveRecord::RecordNotFound

I am trying to learn Rails and am making my first app and am running into this error:
ActiveRecord::RecordNotFound in PartsController#show
Couldn't find Part with id=new_ic
with the highlighted source:
def set_part
#part = Part.find(params[:id])
end
I am brand new to rails and i can't figure out what is wrong and I can't find any help online either. The app is a part management system for electronic components. The form gets filled out and the data is saved to the database for future reference/updating. Could someone please help?
Source code time:
parts/_ic_form.html.erb
<h1>Add An IC</h1>
<%= simple_form_for #parts do |f| %>
<%= f.input :component_type, :as => :hidden, :input_html => { :value => "IC"} %>
<%= f.input :ic_model, label: 'IC Model' %>
<%= f.input :ic_manufacturer, label: 'IC Manufacturer' %>
<%= f.input :ic_pinCount, label: 'IC Pin-Count' %>
<%= f.input :ic_mountType, collection: ["Through Hole", "Surface Mount"], label: 'IC Mount Type' %>
<%= f.input :ic_package, label: 'IC Package' %>
<%= f.input :ic_quantityOnHand, label: 'Quantity On Hand' %>
<%= f.input :ic_quantityOnOrder, label: 'Quantity On Order' %>
<%= f.button :submit %>
<% end %>
parts/new_ic.html.erb
<%= render 'ic_form' %>
parts/new.html.erb
<h1>New part</h1>
<%= link_to 'IC', 'new_ic' %>
<%= link_to 'Back', parts_path %>
parts_controller.rb
class PartsController < ApplicationController
before_action :set_part, only: [:show, :edit, :update, :destroy]
before_filter :initialize_parts
def initialize_parts
#parts = Part.new
end
# GET /parts
# GET /parts.json
def index
#parts = Part.all
end
# GET /parts/1
# GET /parts/1.json
def show
end
# GET /parts/new
def new
#part = Part.new
end
# GET /parts/1/edit
def edit
end
# POST /parts
# POST /parts.json
def create
#part = Part.new(part_params)
respond_to do |format|
if #part.save
format.html { redirect_to #part, notice: 'Part was successfully created.' }
format.json { render action: 'show', status: :created, location: #part }
else
format.html { render action: 'new' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /parts/1
# PATCH/PUT /parts/1.json
def update
respond_to do |format|
if #part.update(part_params)
format.html { redirect_to #part, notice: 'Part was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# DELETE /parts/1
# DELETE /parts/1.json
def destroy
#part.destroy
respond_to do |format|
format.html { redirect_to parts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_part
#part = Part.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def part_params
params[:part]
end
end
routes.rb Pretty sure i screwed this one up too
Pms::Application.routes.draw do
resources :parts
resources :parts
root to: "parts#new_ic"
end
rake routes Output:
Prefix Verb URI Pattern Controller#Action
parts GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
new_part GET /parts/new(.:format) parts#new
edit_part GET /parts/:id/edit(.:format) parts#edit
part GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
GET /parts/new(.:format) parts#new
GET /parts/:id/edit(.:format) parts#edit
GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
root GET / parts#new_ic
One problem is in this line:
<%= link_to 'IC', 'new_ic' %>
link_to should look like this:
link_to "Profile", profile_path(#profile)
#Profile is the name
#profile_path(#profile) is the link
Try this instead:
#parts/new.html.erb
<%= link_to 'IC', root_path %>
in your routes, root GET / parts#new_ic is linking to your new_ic action. I'd disagree with the way you access it (via root) - but it will work if you want to access the new_ic action. Why is this your root route, though?

Resources