Not sure what's going on. I've used the following bit of code to try and edit the name of a category, but I'm getting the error message above. My code for the form and submit for the edit is: -
<% form_for :category, :url => categories_url(#category),:html => { :method => :put } do |f| -%>
<p>Name: <br /><%= f.text_field :name, :size => 60 %></p>
<%= submit_tag 'Save' %> or <%= link_to 'cancel', admin_categories_url%>
So pretty straight forward stuff. My controller code is: -
def edit
#category = Category.find(params[:id])
end
# PUT /categories/1
# PUT /categories/1.xml
def update
#category = Category.find(params[:id])
#category.update_attributes(params[:category])
respond_to do |wants|
wants.html { redirect_to admin_categories_url }
wants.xml { render :xml => #category.to_xm }
end
end
This code has worked for other things - such as blog articles, so I'm not sure where I{"m going wrong. Help??
I think you want :url => category_url(#category) (non-plural).
This tends to be a bit cleaner... Let the Routing system figure out how best to save the #category.
/app/controllers/admin_categories_controller.rb (guessed at this)
def new
#category = Category.new
end
/app/views/admin_categories/new.html.erb
<% form_for #category do |f| %>
<p>
<%= f.label :name%>: <%= f.text_field :name, :size=>60%>
</p>
<%= f.submit :save%> or <%= link_to 'cancel', admin_categories_url%>
Related
I am Rails newbie. I am creating a section that is pulling existing user's details and when the user click on edit, he can save the changes he has made. However, the changes aren't reflecting once the user saves it. Can you tell me what I am missing in here?
Here's the html/ruby form I am using:
<%= form_tag(html: {:id => 'user_profile_form'}, :url => patient_profile_path(#user), :method => :put) do %>
<%= text_field_tag(:inputFieldName, "#{#user.first_name} #{#user.last_name}", {:disabled => true}) %>
<%= submit_tag 'Save', :id=> 'saveButton' %>
<%= end %>
Here's the routes:
put :patient_profile, to: 'users#patient_profile'
post :dashboard, to: 'dashboard#index'
Here are the controller codes:
def patient_profile
if params[:user]
u = params[:user]
#user.first_name = u[:first_name] unless u[:first_name].nil? || u[:first_name].empty?
#user.last_name = u[:last_name] unless u[:last_name].nil? || u[:last_name].empty?
#user.save!
# index
render :index
end
end
It doesn't look like your form is actually updating anything since your form fields don't match your model. Try simplifying your form action:
View
<%= form_for(#user, html: {:id => 'user_profile_form'}, :url => patient_profile_path(#user), :method => :put) do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.submit "Update User" %>
<%= end %>
Controller:
def patient_profile
# TODO: Handle failed validation
#user.update_attributes!(params[:user])
# index
render :index
end
end
def user_params
params.require(:user).permit(:first_name, :last_name)
end
I have a search box at the top of my view as follows
<%= form_tag clients_path(#client), :method => 'get' do %>
<h2> Search for Workflows </h2>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
This is calling my show controller
def show
#client = Client.find(params[:id])
#workflows_raw = Workflow.where(:client_id => #client.id)
unless params[:search].blank?
#workflows_raw = #workflows_raw.search(params[:search])
end
#workflows = #workflows_raw.sort_by {|flow| flow.name}
respond_to do |format|
format.html
format.js
end
end
What I am getting back is this:
http://localhost:3000/clients.4?utf8=%E2%9C%93&search=Add
What I WANT to get back is this: (Note the slash)
http://localhost:3000/clients/4?utf8=%E2%9C%93&search=Add
What am I missing?
You should be using client_path(#client) in your form_tag line (note the singular client_path vs the plural clients_path)
I'm doing a Rails tutorial, and trying to figure out why this is happening.
I'm making a to-do list, and everytime I try and insert a record into my Todo model, I get the following:
Here is the new.html.erb view that this is from:
<h1>Add new item to your todo listM</h1>
<%= form_for #todo, :url=>todo_path(#todo) do |f| %>
<%= f.label :name %> <%= f.text_field :name%>
<%= f.hidden_field :done, :value => false %>
<%= f.submit "Add to todo list" %>
<% end %>
Here is index.html.erb from where the user is linked to new.html.erb
<h1>TASKS</h1>
<h3> TO DO </h3>
<ul>
<% #todos.each do |t| %>
<li>
<strong><%= t.name %></strong>
<small><%= link_to "Mark as Done", todo_path(t), :method => :put %></small>
</li>
<% end %>
</ul>
<h3> DONE </h3>
<ul>
<% #todones.each do |t| %>
<li>
<strong><%= t.name %></strong>
<small><%= link_to "Remove", t, :confirm => "You sure?", :method => :delete %></small>
</li>
<% end %>
</ul>
<%= link_to "Add new task", new_todo_path %>
Here is the TodoController I have managing these actions:
class TodoController < ApplicationController
def index
#todos = Todo.where(done:false)
#todones = Todo.where(done:true)
end
def new
#todo = Todo.new
end
def todo_params
params.require(:todo).permit(:name, :done)
end
def create
#todo = Todo.new(todo_params)
if #todo.save
redirect_to todo_index_path, :notice => "Your todo item was created!"
else
render "new"
end
end
def update
#todo = Todo.find(params[:id])
if #todo.update_attribute(:done, true)
redirect_to todo_index_path, :notice => "Your todo item was marked done!"
else
redirect_to todo_index_path, :notice => "Couldn't update your task"
end
end
def destroy
#todo = Todo.find(params[:id])
#todo.destroy
redirect_to todo_index_path, :notice => "Your todo item was deleted"
end
end
And finally the routes.rb
Oneday::Application.routes.draw do
devise_for :users
root 'home#index'
resources :todo
end
Any input as to why this is happening and how to rectify it would be great.
You do not comply with the rails convention. Use plural form for resources. Then, your action is correct.
TodosController, todos_controller.rb, resources :todos
( Rails use singular/plural format to support RESTful links and to recognize named actions )
This
<%= form_for #todo, :url=>todo_path(#todo) do |f| %>
will set (or leave) the form http method to get. You could change it to:
<%= form_for #todo, :url=>todo_path(#todo), method: :post do |f| %>
or even shorter, leave it to Rails to find out what method is needed:
<%= form_for #todo do |f| %>
I found a fix to this exact issue if anyone is still curious, i know its an old issue and an easy one at that, but still figured id solve it. the original route todo_path leads to todo#show. todo_index however is assigned to todo#index and todo#create so its what we want. the line should look like this:
<%= form_for #todo, :url => todo_index_url(#todo), method: :post do |f| %>
I encountered a similar issue with one of my applications and stumbled across this post as a fix. None of the suggestions worked for me, but i was able to fix it with a little tinkering on the routes.
Sorry for this question but I can't find my error!
In my Project I have my model called "team".
A User can create a "team" or a "contest". The difference between this both is, that contest requires more data than a normal team.
So I created the columns in my team table.
Well... I also created a new view called create_contest.html.erb :
<h1>New team content</h1>
<% form_for #team, :url => { :action => 'create_content' } do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_area :description %>
</p>
<p>
<%= f.label :url %><br />
<%= f.text_fiels :url %>
</p>
<p>
<%= f.label :contact_name %><br />
<%= f.text_fiels :contact_name %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
In my teams_controller, I created following functions:
def new_contest
end
def create_contest
if #can_create
#team = Team.new(params[:team])
#team.user_id = current_user.id
respond_to do |format|
if #team.save
format.html { redirect_to(#team, :notice => 'Contest was successfully created.') }
format.xml { render :xml => #team, :status => :created, :location => #team }
else
format.html { render :action => "new" }
format.xml { render :xml => #team.errors, :status => :unprocessable_entity }
end
end
else
redirect_back_or_default('/')
end
end
Now, I want on my teams/new.html.erb a link to "new_contest.html.erb".
So I did:
<%= link_to 'click here for new contest!', new_contest_team_path %>
When I go to the /teams/new.html.erb page, I get following error:
undefined local variable or method `new_contest_team_path' for #<ActionView::Base:0x16fc4f7>
So I changed in my routes.rb, map.resources :teams to map.resources :teams, :member=>{:new_contest => :get}
Now I get following error: new_contest_team_url failed to generate from {:controller=>"teams", :action=>"new_contest"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: ["teams", :id, "new_contest"] - are they all satisfied?
I don't think adding :member => {...} is the right way doing this. So, can you tell me what to do? I want to have an URL like /teams/new-contest or something.
My next question: what to do (after fixing the first problem), to validate presentence of all fields for new_contest.html.erb? In my normal new.html.erb, a user does not need all the data. But in new_contest.html.erb he does. Is there a way to make a validates_presence_of only for one action (in this case new_contest)?
UPDATE:
Now, I removed my :member part from my routes.rb and wrote:
map.new_contest '/teams/contest/new', :controller => 'teams', :action => 'new_contest'
Now, clicking on my link, it redirects me to /teams/contest/new - like I wanted - but I get another error called:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
I think this error is cause of #team at <% form_for #team, :url => { :action => 'create_content_team' } do |f| %>
What to do for solving this error?
I'm not sure about how your models work, but in my code I've always written;
#team.user_id = #current_user.id
instead of
#team.user_id = current_user.id
That would mean the id wasn't being passed to the controller giving you the error, wouldn't it?
Okay, I found my errors.
For the record:
First of all, I forgot to write the code inside my def new_contest. Here it is:
def new_contest
if #can_create
#team = Team.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #team }
end
else
redirect_back_or_default('/')
end
end
There were several typos, too, in my .erb file like text_fiels instead of text_field or create_content instead of create_contest.
current_user is working fine for me.
Woo. My first question.
I have a feeling I'm overlooking something pretty basic in the construction of my form. I'm using attachment_fu and can't get this form to pass anything besides the file data. A user has_many profiles and a profile has_many documents.
My form looks like this:
<%= error_messages_for :document %>
<% form_for([#user, #profile, #document], :html => {:multipart => true }) do |f| -%>
<p>
<label for="document">Upload A document:</label>
<%= f.file_field :uploaded_data %>
</p>
<%= f.label :description%>
<%= f.text_field :description%>
<p>
<%= submit_tag 'Upload' %>
</p>
<% end -%>
And here's the controller:
before_filter :require_user, :get_profile
def new
#document = #profile.documents.build
end
def create
#document = #profile.documents.build(params[:document])
if #document.save
flash[:notice] = 'Your document was successfully created.'
redirect_to document_url(#document)
else
render :action => :new
end
end
private
def get_profile
#user = current_user
#profile = #user.profiles.find(params[:profile_id])
end
The logs show all the image data getting posted, but I cannot pass the description or, more importantly, the profile_id, which is the foreign key in my document model. I was stuck on this all night, and can't think of anything fresh this morning. Any help would be great.
For the profile_id you will need something like:
<%= f.hidden_field :profile_id %>
Which in your controller you will get at using params[:document][:profile_id] if needed.
Although from trying to guess at what your code is doing, I suspect that params[:profile_id] is already set from whatever route got you to this controller.
I am not sure why you aren't seeing anything for the description. It should be coming into your controller as params[:document][:description].