Given a classic controller action. Have a look at the MARK. I need to set the status code to 200 for the response. Background: swfupload an ajax file upload solution seems to send data in a wrong format.
I tried response.headers['Status'] = 200, response.status 200, render :json => 'data', :status => 200. But the response's status code doesn't change.
def create
if params[:Filedata]
#medium = Medium.new(:swf_uploaded_data => params[:Filedata])
else
#medium = Medium.new(params[:medium])
end
respond_to do |format|
if #medium.save
format.html { redirect_to(#medium, :notice => 'Medium was successfully created.'); }
format.xml { render :xml => #medium, :status => :created, :location => #medium; }
MARK
else
format.html { render :action => "new" }
format.xml { render :xml => #medium.errors, :status => :unprocessable_entity }
end
end
end
The status code can only be declared within the return commands like render, redirect_to .... and will affect to this return command, there is no way to set the code for all the responses
For format.html { redirect_to(#medium, :notice => 'Medium was successfully created.'); } since is a redirection the code will be a 3XX and you can't change it or the redirection won't work
For format.xml { render :xml => #medium, :status => :created, :location => #medium; } you are declaring the status as created, this means for rails that the code is 201, for making it a 200 change it for:
format.xml { render :xml => #medium, :status => :ok, :location => #medium; }
What format is the AJAX call expecting in response? You're only responding to HTML and XML, so if it's expecting JavaScript or JSON, that might be a problem.
Also, I'm not sure if this matters, but I've never seen a condition inside the respond_to block like you've shown. Usually it's like this:
if #medium.save
respond_to { |format| ... }
else
respond_to { |format| ... }
end
I'm also not clear what the "MARK" is supposed to be.
Related
When a user POSTs JSON to the /update/ action in a Rails 3 app, what is the best way to respond?
I want to just send an empty JSON response with a 200 code, something like
head :no_content
or
render :nothing => true, :status => 204
(examples from How to return HTTP 204 in a Rails controller).
Typically I have been doing this:
render :json => {}
or
render :json => 'ok'
Is there preferred or more Rails-y way to this?
My Rails 3 app uses code such as this for updates. The code for html and xml was auto generated by Rails, so I just added in the JSON renderer using the same format.
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to(#product, :notice => 'Product was successfully updated.') }
format.xml { head :ok }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #product.errors, :status => :unprocessable_entity }
format.json { render :json => #product.errors, :status => :unprocessable_entity }
end
end
Works perfectly, which is what's ultimately important.
What I'm trying to do is update a created item's attributes after it is created through the controller, like so:
def create
#check_out = CheckOut.new(params[:check_out])
#check_out.request_id = #request.id
#check_out.status = 'complete'
#check_out.date_taken = Time.now
etc.....
respond_to do |format|
if #check_out.save
format.html { redirect_to(#check_out, :notice => 'Check out was successfully created.') }
format.xml { render :xml => #check_out, :status => :created, :location => #check_out }
else
format.html { render :action => "new" }
format.xml { render :xml => #check_out.errors, :status => :unprocessable_entity }
end
end
end
The issue is that the item created, is created via a nested attribute. I've come to realize, through painful trial and error, that when nested items are created, it is not through their controller, but some other way. I need to figure out how this is done, so I can attempt to come up with a solution.
The good place to start http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for
In our rails application we have a page where upon submit we save data in db. On this page, we have some fields which are dynamically generated and I see that in case of a validation error when page reloads it doesn't populate these fields with the values present upon posting.
In controller we have the following method defined for populating it:
def build_my_registration_type_memberships
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end end
In above method when my registration is opened in edit/view mode, it shows the values using this #membership method. But on posting in case of error it doesn't reload this with correct information. So my question is how could I repopulate #membership in case of an error on posting?
Thanks for help.
As, I understand you want some values available to your new method or the page that is rendered after if the create fails.
I assume you must have have the respond_to block in your create method. And you're doing this:
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html { render :action => :new }
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
As you can notice, in the else part the new action is just rendered. Using some template the view is just delivered. Now, you just have to do whatever you're doing in the new action to make those values available, in the else part.
def create
...
respond_to do |format|
if #patient.save
format.html { redirect_to #object, :notice => "Object was successfully saved." }
format.xml { render :xml => #object, :status => :created, :location => #object }
else
format.html {
#memberships = []
ListCache.my_registration_types.each do |my_registration_type|
#memberships << MyRegistrationTypeMembership.find_or_initialize_by_my_id_and_my_registration_type_id( #my.id, my_registration_type.id )
end
render :action => :new
}
format.xml { render :xml => #patient.errors, :status => :unprocessable_entity }
end
end
end
And, the values you wanted will be available in the rendered form.
Better, you move to that code to a before filter or something, which makes those values available to those two methods (new and create).
def create
#asset = Asset.new(params[:asset])
respond_to do |format|
if params[:Filedata]
#asset = Asset.new :swf_uploaded_data => params[:Filedata]
#asset.user = current_user
#asset.save!
format.html { render :text => #asset.image.url(:thumb) }
format.xml { render :nothing => true }
else
if #asset.save
flash[:notice] = 'Created'
format.html { redirect_to(#asset) }
format.xml { render :xml => #asset, :status => :created, :location => #asset }
else
format.html { render :action => "new" }
format.xml { render :xml => #asset.errors, :status => :unprocessable_entity }
end
end
end
end
I am creating an upload status bar with swfupload. At the end of the upload I get a 406 error.
Not necessarily your answer but I had the same problem with Plupload and it happens that the request format is nil.
It might not be the best way but one could do the following:
request.format ||= :xml
in order to provide some default format in the method. Hope it can help others.
Basically I am trying to capture the value of the form field before it is saved to the database. Then I intend to use that value in my controller to update a specific field in the database,
using
#taskforms.update_attribute('notes',
$notes)
I need to do this because I know of no other way to update that that does not require the full record to be validated.
The suggestion below to use #taskforms.save(false) is really not what I was looking for optimally. However it could work. However having and issue to get it to work.
What I am currently using (that works with validations)
def myupdate
#taskforms = Taskforms.find(params[:id])
respond_to do |format|
if #taskforms.update_attributes(params[:taskforms])
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
end
However when I try the save(false) it doesn't save and triggers validations anyway
def myupdate
#taskforms = Taskforms.find(params[:id])
if #taskforms.save(false)
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
I have never used Save in the past just the default respond_to do |format| so suspect my code is incorrect.
#taskforms.save(false) will save your model without any validations if that is your main goal.