I'm following the Head First Rails book, and having lots of trouble with it as it uses Rails 2, not 3. At the moment, I'm going through the part where it gets you to create a system for booking seats on a flight. The flight's show page has a partial for the seats booked, and a form so that you can book a seat.
I cannot for the life of me get the system to work so that when you click 'book seat' the changes immediately appear in the seat list above. Rails keeps complaining that when I click 'book seat' that there is a missing template for seats/update. I'm even using the 'answers code' directly off the head first site and it still isn't working! Please can someone help!!
Problem 1:
Here is the controller code for the seats:
def create
#seat = Seat.new(params[:seat])
render :update do |page|
if #seat.save
page.replace_html 'notice', 'Seat was successfully booked'
else
page.replace_html 'notice', 'Sorry - the seat could not be booked'
end
page.replace_html 'seats', :partial => 'flights/seat_list',
:locals => {:seats => #seat.flight.seats }
end
end
# PUT /seats/1
# PUT /seats/1.xml
def update
#seat = Seat.find(params[:id])
respond_to do |format|
flash[:notice] = 'Seat was successfully updated.'
format.html { redirect_to(#seat) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #seat.errors, :status => :unprocessable_entity }
end
end
end
Problem 2:
When trying to 'ajaxify' the form, the book is telling me to use remote_form_for, which as I understand it, doesn't appear in rails 3. So I have tried using:
<h1>New seat</h1>
<% form_for(seat), :remote => true do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :flight_id %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :baggage %><br />
<%= f.text_field :baggage %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
But that gives me an error of
Showing c:/Ruby193/coconut/app/views/flights/_new_seat.html.erb where line #2 raised:
c:/Ruby193/coconut/app/views/flights/_new_seat.html.erb:2: syntax error, unexpected ',', expecting keyword_end
'); form_for(seat), :remote => true do |f|
^
c:/Ruby193/coconut/app/views/flights/_new_seat.html.erb:18: syntax error, unexpected keyword_ensure, expecting $end
I'm banging my head against the wall here, any help would be much appreciated!!
Get rid of the comma in _new_seat.html.erb and add the equal sign
<%= form_for(seat), :remote => true do |f| %>
Related
I've got a Rails application that is using nested forms. Details follow and I tried this solution (Rails 3 Nested Models unknown attribute Error), but for some reason, the field is repeating multiple times instead of listing and saving the options correctly. Thanks in advance for your help!
Model information for Newsavedmaps
has_many :waypoints, :dependent => :destroy
accepts_nested_attributes_for :waypoints
Newsavedmap_controller
def new
#newsavedmap = Newsavedmap.new
waypoint = #newsavedmap.waypoints.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #newsavedmap }
end
end
def edit
#newsavedmap = Newsavedmap.find(params[:id])
if #newsavedmap.itinerary.user_id == current_user.id
respond_to do |format|
format.html # edit.html.erb
format.xml { render :xml => #activity }
end
else
redirect_to '/'
end
end
Maptry View
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoint do |w| %>
<%= w.select :waypointaddress, options_for_select(Waypoint.find(:all, :conditions => {:newsavedmap_id => params[:newsavedmap_id]}).collect {|wp| [wp.waypointaddress, wp.waypointaddress] }), {:include_blank => true}, {:multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints"} %>
<% end %>
<% end %>
When I use the above code, my form works correctly, but submitting it gives me this error:
UnknownAttributeError (unknown attribute: waypoint)
When I change ":waypoint do |w|" to ":waypoints do |w|" in the view, the select field disappears when the user is creating a new record, and in the edit view, the select field appears several times (however many waypoints the user saved in the record.)
How can I get this form field to work properly?
EDIT 1
Here is my latest attempt. For new records, the select field does not appear. However, in the edit view, the select field appears multiple times. This is a Rails 2 application, FYI. Taking a cue from the comments, I used a collection_select approach (not collection_for_select because I couldn't find documentation for that.) Again, I appreciate your help!
<% f.fields_for :waypoints do |w| %>
<%= w.collection_select( :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, {:include_blank => true}, {:id =>"waypoints"} ) %>
<% end %>
Your form has the following problems.
Use f.fields_for :waypoints since the argument needs to match the name of the association.
Use collection_select rather than select, since you have an ActiveRecord model behind that field.
So, taking that into account, you could try this for your form:
<% form_for #newsavedmap, :html => { :id => 'createaMap' } do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoints do |w| %>
<%= w.collection_for_select :waypoint, :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, { :include_blank => true }, { :multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints" } %>
<% end %>
<% end %>
The API for collection_select is a bit tricky to get right. I usually need a few attempts as well. This previous SO question may help clear things up: Can someone explain collection_select to me in clear, simple terms?
Tis is my view:
<%= form_for item, :url => comment_item_path(item), :html => {:remote => true, 'portal-transform' => true, :multipart => true} do |f| -%>
<%= f.fields_for :updates, Update.new, :index => nil do |m| -%>
<%= m.text_area :comment %><br />
<%= m.file_field :attachment %>
<% end -%>
<%= f.submit "Comment" %>
<% end -%>
And controller action:
respond_to do |format|
format.js do
render :json => {}
end
end
When I submit the form with only comment (text_area) field entered and keep attachment (file_field) field blank, it render exactly what expected.
But when I submit the form with attachment, it resulted in:
Completed 406 Not Acceptable in 56ms
What went wrong for me? Please guide.
Thanks.
Browsers do not allow file uploads via AJAX for security reasons. If you leave the form's file_field blank however, the form submits normally with no error, which explains the behaviour you are seeing.
To upload files via AJAX in Rails 3, you can use the Remotipart gem.
http://os.alfajango.com/remotipart/
Here is an example usage:
http://thechangelog.com/post/7576700785/remotipart-rails-3-ajax-file-uploads-made-easy
i have simple upload form:
<%= form_for(:product, :url => {:action => 'update_product', :id => #product.id}, :html => {:multipart => true}) do |f| %>
<%= f.file_field(:product_image) %>
<%= submit_tag('Upload') %>
<% end %>
And in a controller:
def update_product
product = Product.find(params[:id])
if(product)
uploaded_image = params[:product][:product_image]
params[:product][:product_image] = uploaded_image.original_filename
product.update_attributes(params[:product])
flash[:notice] = "Successfully updated!"
redirect_to :action => 'edit_product', :id => product.id
end
end
When i try to upload, i have an error "undefined method `original_filename' for nil:NilClass"
What i'm doing wrong?
I use Rails 3.0.10 and Ruby 1.9.2p290
My guess is params[:product][:product_image] is nil.
Try to use gem for file uploads.
Sources
1.Paperclip
2.Carrierwave
I've had this symptom, but intermittently. Sometimes the browser (chrome) seems not to select the file from the 'Choose File' dialogue box. On one occasion I saw that after double-clicking a file in the dialogue box it took several seconds to show as the selected file back in the browser window. I guess if you hit 'submit' before the files is effectively selected then you'll get that error.
<h2>Choose file to upload ...</h2>
<%= form_tag({:action => :sched_file_uploader}, :multipart => true) do %>
<%= file_field_tag 'schedfile' %>
</br></br>
<%= text_area_tag(:file_info, "<care to say anything about this file?>", :size => "24x6") %>
</br></br>
<input name="upload" type="submit" value="Upload" />
<% end %>
please remove this line:
params[:product][:product_image] = uploaded_image.original_filename
def update_product
product = Product.find(params[:id])
if(product)
uploaded_image = params[:product][:product_image].original_filename
product.update_attributes(params[:product])
flash[:notice] = "Successfully updated!"
redirect_to :action => 'edit_product', :id => product.id
end
end
HI
I tried using a javascript function call in the submit tag of a form_remote_for but it is not able to find the function im calling.
if i call the same function from form_remote_for then ajax stops working.
can ny one help me how can i call an javascript function when im using form_remote_for NOT FORM_REMOTE_TAG....????
I think REMOTE_FORM_FOR is what you need.
example:
In your view:
<%- remote_form_for(comment, :url => topic_post_comments_path(#topic, post),
:after => "submitComment(self);$('input').disable()") do |f| %>
<%= f.text_field :body, :size => 70, :class => "comment_body" %><br />
<%= f.submit "Submit", :class => "comment_submit" %>
<%- end -%>
Notice: the javascript function in :after is my custom javascript functions.
And in your controller (it's comments_controller here)
#comment = #post.comments.new params[:comment] # actually, it depends on your model :p
respond_to do |format|
# remember to handle exception here. like if #comment.save or not
format.html
format.js {
render :update do |page|
pagepage.visual_effect :highlight, "comments"
end
}
end
anyway it's just a easy sample, you have to handle more details after you get some feeling for remote_form_for.
Good luck.
So my background is in Java web services, but I'm trying to make the move to ROR.
I'm using FlexImage to handle image uploading and thumbnail generation. I followed the guide and CRUD behavior was working fine at one point. However, at some point, CRUD behavior for one of my models (Images) was broken.
The error code I'm getting back is as follows: ActiveRecord::RecordNotFound in ImagesController#show -- Couldn't find Image with ID=#<Image:0x4e2bd74>. In other words, when I'm telling Rails to create/update/destroy, it is confusing the object with the id. This seems to indicate there might be a routing issue. I thought adding a partial for images might have been the trouble, but rolling back the changes didn't fix it.
Following are the new, show and update methods of the controller for the Images model:
# images_controller.rb
# ...
def new
#image = Image.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #image }
end
end
# ...
def show
#image = Image.find(params[:id])
respond_to do |format|
format.jpg # show.jpg.erb
format.html # show.html.erb
format.xml { render :xml => #image }
end
end
# ...
def create
#image = Image.new(params[:image])
if #image.save
redirect_to image_url(#image)
else
flash[:notice] = 'Your image did not pass validation.'
render :action => 'new'
end
end
# ...
Note that show() is, of course, expecting an appropriate id. Here's the new.html.erb for uploading a new image:
# new.html.erb [upload image]
<h1>New image</h1>
<% form_for #image, :html => { :multipart => true } do |f| %>
<%= f.error_messages %>
<table><tr><td width="50%">
<p>
<%= f.label :filename %><br />
<%= f.text_field :filename %></p>
</td>
<td><p><b>Upload Image</b><br />
<%= f.file_field :image_file %><br />
or URL: <%= f.text_field :image_file_url %>
<%= f.hidden_field :image_file_temp %>
</td>
<td>
<b>Uploaded Image:</b><br />
<%= embedded_image_tag(#image.operate { |img| img.resize 100 }) if #image.has_image? %>
</td>
</tr>
</table>
<p>
<%= f.label :description %><br />
<%= f.text_area :description %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<%= link_to 'Back', images_path %>
The relevant portion of routes.rb are as follows:
# routes.rb [excerpt]
map.resources :images
map.image 'images/:action/:id.:format', :controller => 'images'
Also note that a new image does actually get uploaded and the error is thrown on redirect to show (which is expecting a valid ID in params[:id] and not the object which for whatever reason it is being handed.)
Thanks for your help in advance, and please let me know if anything jumps out at you.
From looking at the code it appears to me that the problem may be caused by using image_url(#image) in combination with the non-RESTful image route.
You will probably want to remove the line
map.image 'images/:action/:id.:format', :controller => 'images'
from your routes.rb.
The line
map.resources :images
should actually be enough to expose all CRUD actions in your ImagesController.
My suggestion is to use ruby-debug and set a break point right before the Image.find call. Inspect params[:id] and see what it actually is.
A more ghetto approach, put this before the Image.find call
logger.info params[:id].class
and see what is in that variable. Is it possible that you have some sort of before filter that is manipulating it?
try
redirect_to :action => "show", :id => #image
I think that's a more idiomatic way to code the redirect. And +1 to molf's advice about RESTful routes.