Ruby on Rails: Why "edit" action does not work? - ruby-on-rails

In views/products/edit.html.erb I use:
<%= form_for(:product, :url => {:action => 'update', :id => #product.id}) do |f| %>
which generates:
<form method="post" action="/aircons/8" accept-charset="UTF-8">
and I get the following error:
The action '8' could not be found for ProductsController
when trying to update a product with id=8.
I think that form's method should be put. Is that right ? How should I fix this ?
Some controller code:
def edit
#product = Product.find(params[:id])
end
def update
update_params_with_new_values(params)
#product = Product.find(params[:id])
if #product.update_attributes(params[:product])
flash[:notice] = "Product updated successfully."
redirect_to(:product => 'index')
else
render('edit')
end
end
def update_params_with_new_values(params)
params[:product][:shop_id] = Shop.create(:name => params[:new_shop]).id if params[:product][:shop_id] == "new_shop"
params[:product][:brand_id] = Brand.create(:name => params[:new_brand]).id if params[:product][:brand_id] == "new_brand"
end
routes.rb contains only the following two lines:
root :to => "products#index"
resources :products

Why don't you just use:
<%= form_for #product do |f| %>
?
If it won't work, please add your routes to question.

try using this
<% form_for #product %>
#code goes here
<% end %>
you need not do all the things that you are trying. If you have created this Product model using scaffolding mechanism you must have its entry in the config/routes.rb file this will give you a path variable as below
GET /products/:id/edit edit return an HTML form for editing a photo
PUT /products/:id update update a specific photo
you can get the edit path as edit_product_path for more info on this have a look at this
Hope you understand it better now.

Related

Disable auto redirect_to in rails app

Can I disable auto redirect in ruby on rails, here my example: In my controllers
class WelcomeController < ApplicationController
def index
#a = params[:link]
if #a != nil
Kernel.system("ls")
redirect_to root_path
else
end
end
end
I don't want to redirect to root_path and stay in current pages, so I remove redirect_to root_path, like this:
def index
#a = "abcd"
if #a != nil
Kernel.system("ls")
else
end
end
But my app still auto redirect to root_path, I don't know how to fix that, please! help me:)
my routes:
root 'welcome#index'
match '/upload', to: 'welcome#index', via: 'post'
my html:
<%= form_tag(upload_path, :id => "form_check") do %>
<%= text_field_tag :link %>
<%= submit_tag("Process")%>
<%end%>
I think your problem isn't really auto redirect. You are "redirected" to your index because this line doesn't match: match '/upload', to: 'welcome#index', via: 'post'.
What you should do is to separate index and upload. It will be far easier to manage.
routes:
root 'welcome#index'
get 'form' => 'welcome#form', as: :form_path
post 'upload' => 'welcome#upload', as: :upload_path
form page:
<%= form_tag(upload_path, :id => "form_check") do %>
<%= text_field_tag :link %>
<%= submit_tag("Process")%>
<%end%>
And then you can create your new actions inside welcome, called form and upload. The last one redirect you to /form, so you can see your form again.

Update method "No route matches [POST]"

Having a bit of trouble with the following ruby on rails code snippet - I have books and would like to update a book's name, here is how I try to do it:
<h1>Edit the book "<%= #book.name %>"</h1>
<%= form_tag action: :update, id: #book do %>
<p>
<label for="book_name">Name</label>
<%= text_field :book, :name %>
<%= submit_tag 'Save changes' %>
</p>
<% end %>
This is what I do in the books controller:
def edit
#book = Book.find(params[:id])
end
def update
#book = Book.find(params[:id])
if #book.update_attributes(params[:book])
redirect_to :action => 'show', id => #book
else
#subjects = Subject.find(:all)
render :action => 'edit'
end
end
These are my routes:
root to: 'authors#index'
resources :books, :authors
When I click the submit button in the form, it gives me No route matches [POST] "/books/5" and directs to localhost:3000/books/5 instead of staying and localhost:3000/books/5/edit
What am I doing wrong here? Shouldn't there be a put method for updating stuff somewhere rather than a post method?
Updates should use put not post.
<%= form_tag( { :controller => :books, :action => :update, :id => #book.id }, { :method => :put } ) do %>
or better yet use form_for
<%= form_for #book do |f| %>
On your console run "rake routes" and it will print out all available routes.
Please try this:
We need to specify match in routes file.
match "/books/:id" => "books#update"
resources :books should do the job. you dont have to explicitly use "match".
def edit
#book = Book.find(params[:id])
end
form.html
form_for #book, :method => :put do |f|
def update
#book = Book.find(params[:id])
#book.update_attributes(params[:book])
end
this should do the job.
I had this issue before. Everything was right but still getting the error then I found out it was
gem 'rails-api'
Removed it and it all worked fine.

Update database using 'update_attributes' through 'has_many'

I'm having a problem getting my first app (I'm a total newbie) to save a new associated record. I have two models (users and pictures) with a has_many/belongs_to association. I have set up the userController so that it can create a new picture as below:
def new_picture
#user = User.find(current_user.id)
#picture = #user.pictures.build
end
def create_picture
#user = User.find(params[:id])
#picture = #user.pictures.build(params[:picture])
if #picture.save
flash[:notice] = "Your picture was successfully added."
redirect_to :action => 'show', :id => #user.id
else
render :template => "new_picture"
end
end
and I use
<%= link_to("add picture", :action => 'new_picture', :id => #user.id) if current_user %>
to add a new one. But I'd also like to be able to edit. So I updated the usercontroller with some new code:
def edit_picture
#user = User.find(current_user.id)
#picture = #user.pictures.find(params[:id])
end
# When the user clicks the save button update record
def update_picture
#user = User.find(current_user.id)
#picture = #user.pictures.find(params[:picture])
respond_to do |format|
if #picture.update_attributes(params[:picture])
flash[:notice] = "Your picture was successfully updated."
redirect_to :action => 'show', :id => #user.id
else
render :template => "new_picture"
end
end
end
and added the edit link to show.erb:
<%= link_to("edit picture", :action => 'edit_picture', :id => picture.id) if current_user %>
It loads the edit form fine, with the data all in the right place, but on save all it's doing is giving me the error 'ArgumentError in UsersController#update_picture' with a bunch of Unknown key(s) from my pictures table.
Could somebody explain why? I feel like there is one piece of the jigsaw I haven't quite understood here....
Thanks in advance!
UPDATE: View code is as follows:
<h1>New picture for <%= #user.name %></h1>
<% form_for :picture, #picture, :html => { :multipart => true }, :url => {:action => 'update_picture', :id => #user.id} do |f| %>
Can't seem to see your problem in the view code, however you can do the same thing more elegantly (RESTful) as a nested route. That way you might be able to see the problem more clearly.
config/routes.rb:
resources :users do
member do
resources :pictures
end
end
app/controllers/pictures_controller.rb:
class PicturesController < ApplicationController
before_filter :find_picture, :only => [:edit, :update]
def edit
end
def update
if #picture.update_attributes params[:picture]
flash[:notice] = "Your picture was successfully updated."
redirect_to user_path(current_user)
else
render :edit
end
end
protected
def find_picture
#picture = current_user.pictures.find params[:id]
end
end
app/views/pictures/edit.html.erb:
<%= form_for [current_user, #picture] do |f| %>
<!-- some stuff -->
<% end %>
and to link to your edit form:
<%= link_to_if current_user, 'edit picture',
edit_user_picture_path(:user => current_user, :id => picture) %>
I suggest adding 'accepts_nested_attributes_for :pictures to the user model, and then do
<%= form_for #user do |form| %>
.. user fields
<%= form.fields_for :pictures do |picture_form| %>
.. picture fields
<% end %>
<%= form.submit %>
<% end %>
in the view.
Another option is to create a new controller for the pictures. That may be simpler.

Rails, Posting to a Custom Method

in my group controller I have two methods:
def new
#group = Group.new
respond_to do |format|
format.js
end
end
def new_beta
#group = Group.new
respond_to do |format|
format.js
end
end
I have a form that starts like so:
<%= form_for Group.new, :remote => true do |f| %>
How can I get the form_for to post to the new_beta controller? Thanks
You can set :
<%= form_for Group.new, :url=>{ :action =>"new_beta", :controller =>
"group"}, :remote => true do |f| %>
(you can also -preferably- directly use a named route instead of ":url => ")
First this is bad practice but..
in your routes add
resources :groups do
member do
get :new_beta
post :new_beta_create
end
end
Now
<%= form_for Group.new, :url => new_beta_create_groups_path, :remote => true do |f| %>
However I recommend creating a new controller called something like: alternate_groups_controller. Even better make a namespace for them.
Good luck

Routing is using ID has action and action has ID after submitting a form

I have a model User that has_one user_profile and a User_Profile belongs_to user
in the User controller I have:
def personal
#user = User.find_by_id(params[:id])
#user_profile = #user.user_profile
#user_profile ||= #user.build_user_profile
end
def update_personal
#user = User.find_by_id(params[:id])
if #user.user_profile.update_attributes(params[:user_profile])
flash[:notice] = "OK"
redirect_to #user
else
flash[:notice] = "Fail"
render :action => 'update_personal'
end
end
In my personal.html.erb view I have:
<% semantic_form_for #user_profile, :url => { :action => "update_personal"} do |form| %>
<%= form.inputs %>
<%= form.buttons %>
<%end%>
And on the rountes I have:
map.resources :users, :member => {
:personal => :get,
:update_personal => :put
}
Now the strange thing is that I can do:
users/1/personal
to see the form but when I submit I get this error:
Unknown action
No action responded to 1.
It's trying to find an action with the name 1.
Can anyone point me out on the right direction?
I just got the problem again, and finally understood the problem and found the solution.
This time i was using an ajax call using getJason.
Because the call was a get, and in my routes I had a update_xxxxxx => :put,
the route was ignored and the default :controller/:action/:id was used.
I just had to put the update_xxxx => :get and the problem was solved.
Maybe this will help someone.

Resources