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.
Related
I have a method called "createpost" in "topics_controller" which I am trying access from the show inside "topics_controller" but I keep getting a route error.
The Form:
<%= form_for #community_post, :url => { :action => "createpost", :controller=> "community_topics" } do |f| %>
<%= render 'error_messages' %>
<%= f.label :text %>
<%= f.text_area :text %>
<%= hidden_field_tag :community_topic_id, #community_topic.id %>
<br>
<%= f.submit "Submit reply" %>
The Controller Action:
def createpost
#community_post = CommunityPost.new(community_post_params)
#community_post.user_id = current_user.id
#community_post.community_topic_id = params[:community_topic_id]
if #community_post.save
redirect_to "/community_topics/#{#community_post.community_topic_id}", notice: 'Community post was successfully created.'
else
render action: 'new'
end
end
What am I doing wrong so I can correct it? Thanks a bunch.
You should have in your routes something like:
resources :comunity_topics do
post 'createpost', action: 'createpost'
end
and the form route should be something like:
createpost_comunity_topics_path
Either rename the method createpost in controller to create and remove the url option for form_for in view. Or define the route, if you really want use the createpost action like this:
resources :community_posts do
collection do
post :createpost
end
end
But I suspect that you are following some old tutorial from the times when Rails had routes that contained the name of controller and action to be executed. This approach was abandoned in favor of RESTful routes.
Read the current docs here:
http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
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| %>
I decided to start a little project in rails 3 and I am a little bit stuck on a form... Where can I specified the f.submit action should go to a special controller / action ?
The code in the form is:
<%= form_for #user, :url => { :action => "login" } do |f| %>
<div class="field">
<%= f.text_field :email %><br />
<%= f.text_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
User is defined as #user = User.new in "index" method of "home_controller".
but I have the error:
No route matches {:controller=>"home", :action=>"login"}
as soon as I run http://0.0.0.0:3000
I am very sorry for this newbee question but I cannot find the routing details (I worked a little bit with rails a couple of years ago but...)
Thanks,
Luc
You don't need to specify any action for f.sumbit.
First of all, you need to make sure you put
resources :users
(for example)
in your routes.rb
then if you want to create a user
put
def new
#user = User.new
end
in your users_controller so you have a page to create new user
or you can put #user=User.new anywhere you like, remember to set
the route correctly
then
def create
#user = User.new(params[:id])
if #user.save
sign_in #user
redirect_to #user
else
render 'new'
end
end
is the part that does real work after you hit on submit
the actual part that connect your form with everything else is this line
<% form_for #user do |f| %>
you can change user to other object, and you can also edit form using update action in a controller.
Hope you got the idea
Whenever you use REST objects, the mere:
form_for #article
is enough for the form to find the proper path.
Otherwise, you can use helpers this way:
form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form")
More info here: http://edgeguides.rubyonrails.org/form_helpers.html
I have an erb file named index that has a form in it. As a simple example:
<% form_for #foo, :url => {:action => 'bar'} do |f| %>
<%= f.submit "BAR!" %>
<%end%>
When I click the BAR! button it preforms the actions I expect and it forwards me onto the bar.erb file, displaying the expected output. What I would like to be able to do, however, is to take the generated html from this page and stuff it into the innerHTML of a div on the index page. I assume there is a way but I must ask, is there a way to achieve this? Are there any examples available that would be helpful? Thanks!
You should be able to pass the id of the div to update like so:
<% remote_form_for #foo, :url => {:action => 'bar'}, :update => 'id-of-div-to-update' do |f| %>
<%= f.submit "BAR!" %>
<%end%>
In the controller:
def bar
# your code here
respond_to do |format|
format.html { redirect_to(xxx) }
format.js
end
end
Rails will look for a template named bar.js and will render it and return it's content to the browser without a redirect.
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.