ruby on rails and XML - ruby-on-rails

I am trying to create a ruby on rails app to capture data from form and create a corresponding XML.I have created a dummy model class which is not extending active record
Do i have to do that .Below is the code and the error i m facing plz help
class RamOne
attr_accessor :name,:city
end
Controller
def start
#ramone = RamOne.new
end
def load_new
#ramone = RamOne.new(params[:ramone])
if #ramone.save
redirect_to :action => ‘gen_xml’
end
end
def gen_xml
#xml = Builder::XmlMarkup.new
#ramones = RamOne.find(:all)
render :layout => false
end
View captures name,city and has a submit action attached with load_new
error : wrong num of args(1 for 0 ) in load_new
what is wrong?

You can't call RamOne.new with an argument because your RamOne class does not override the initialize method. Also, #ramone.save and RamOne.find are all ActiveRecord methods, so I think you need to extend ActiveRecord::Base in your RamOne class.

Check out the Hpricot gem http://hpricot.com/ if you are doing some heavy duty XML.
Check out REST to clean up your controller. http://guides.rubyonrails.org/routing.html#restful-routing-the-rails-default

Can i get rid of the model class
and store my captured data in a normal ruby class and fetch from it to create the xml .Are there any helper methods available
similar to form_for() helper
<% form_for :ramone, #ramone, :url => { :action => "load_new" }, :html => { :method => :get } do |f| %>
can i find any other non ActiveRecordHelper methods
I dont want the Model class unnecesarily.

Related

Use Rails logic with JSON data

This may seem a pretty stupid question but I'm out of ideas at the moment and appreciate suggestions.
I have created a quiz interface that should change the question when NEXT button is clicked. The next question is loaded as JSON via AJAX call. Now the question contains HTML and I need to use Rails sanitize helper to filter tags.
I am not sure how I would use sanitize method on JSON data data acquired via AJAX call.
Please guide me.
EDIT:
The stress was not on JSON data. It was an honest mistake. The issue was the inability to use Rails logic on the data returned by AJAX call.
After some research and with the help of this answer, I was able to achieve what I wanted to.
All I had to do was to create a partial template (say, _question.html.erb) for the quiz question container with a form like this:
_question.html.erb
<%= form_tag('/question', :remote => true, :id => 'quiz') do -%>
... some code here ...
<%= submit_tag 'Submit' %>
<% end -%>
Create a route /question in routes.rb:
match 'question', :to => 'quiz#question', via: [:post]
and in QuizController.rb handle the response:
class QuizController < ApplicationController
def question
... some logic here ...
#ques = ...
#options = ...
respond_to do |format|
format.html
format.js
end
end
end
Now, create a question.js.erb to render the template with data:
$('#quiz-container').html("<%= escape_javascript(render partial: 'question',
:locals => { ques: #ques, options: #options }) %>");
The :remote => true option in the form does the trick here. It submits the form via ajax. Now, I can use Rails logic inside the partial template that gets the data via AJAX call.

Manage Single Rails form to other controller with create and update action

i'm new of rails. I use rails 3.0.5 .
I have an EMPLOYEE resource, but I would like to manage it with another extern controller (emp_profile_controller).
This extern controller (emp_profile_controller) manages some actions (index, new_employee, create_employee, edit_employee, update_employee ecc.. ) .
My routes for this controller are :
controller :emp_profile do
get 'emp_profile' => :index
get 'emp_edit_profile' => :edit_employee
put 'emp_edit_profile' => :update_employee
get 'new_employee' => :new_employee
post 'new_employee' => :create_employee
get 'emp_list' => :emp_list
end
How can i use one form to handle both Create and Update actions in this controller ?
I tried with :
form_for(#employee, :url => { :controller => "emp_profile"}) do |f|
but it doesn't work.
If i manage only one action at time (create OR update), url_for works, for example :
form_for(#employee, :url => { :controller => "emp_profile", :action => "update_employee" }
but how can i handle both actions with one form ?
Thanks for your availability and I apologize if I asked a stupid question.
EDIT
For now, i solved checking if object exist in the form file, if exist i set a variable with the UPDATE action path, else, i set a variable with the CREATE action path. So in the form_for statement i use url_for with the above variable.
<% if #employee.new_record?
action = "create_employee"
method = "post"
else
action = "update_employee"
method = "put"
end
%>
form_for(#employee, :url => { :controller => "emp_profile", :action => action }, :method => method
I don't think it is the best way but it works and i can use only one form file.
As your model name and controller name are different, you can add this line to your routes
resources :employees,:controller=>"emp_profile",:path=>"emp_profile"
Change the method names of create_employee,update_employee to create and update respectively.
And change your form_for as given below
<%= form_for #employee do |f| %>
....
<% end %>
First of all, if you want to update something, this object should exist.
How do plan to find it out, I don't know (cause there different ways, depends on background).
There are 2 ways of solving this issue.
You can just check if object exist in view file, and if exists, renfer form for update, else for create.
Other way is to do it in controller.
For example:
def create
#employee=Employee.find_by_name('Jack Black') #for example
if #employee!=nil
render :action=> 'update'
else
#employee=Employee.new(:employee)
#employee.save
end
as i understand you want to execute two different actions on the same controller using a form submitting, this is not possible, you can only execute one action using a form submitting,
because the form is reaching to an action controller that action is suppose to render some view at the end of it's execution code, if it was possible to use to actions on form submitting how rails will know which view to render??? (that's why it's not possible).
if you want to do some more code execution at the controller, the right way to it is to call a method with some code in it that you want to execute, that method should be in the model,
because it is a good practice to write all massive chunks of code in the model and leave the controller as light from code as possible :-)
hope this helps.

Argument error for file uploading with rails 3.1 app

I'm trying to set up a very basic system for uploading files to my rails 3.1 app. Before people start throwing paperclip and carrierwave links at me, let me say that this is NOT the solution that I am looking for. I have read quiet a few posts on this topic, however, all the code I saw was either depreciated in rails 3.1 or I just did not understand how people came to a solution to this problem.
Updated view/form: (haml)
%h1 File Upload
= form_for :upload,:url=>{:action => 'uploadFile'},:html => { :multipart => true } do |f|
%p
%label{:for => "upload_file"} Select File
\:
\#{f.file_field 'datafile'}
= f.submit "Upload"
Updated controller:
class UploadController < ApplicationController
def index
render :file => 'upload/uploadfile.haml'
end
def uploadFile
file_param = params[:upload][:datafile]
post = DataFile.save(file_param)
render :text => "File has been uploaded successfully"
end
end
Updated model
class DataFile < ActiveRecord::Base
def self.save(upload)
# Changed Default Destination: [__RAILS_DIR__/public/data]
name = "public/data/" + upload.original_filename
# can haz data directory?
require 'FileUtils'
FileUtils.mkdir_p(File.dirname(name))
File.open(name, "wb") { |f| f.write(upload.read) }
end
end
The Solution:
Above is the correct code I used to add simple uploading functionality to my rails 3.1 app
You are passing unnecessary argument "file" to the uploadFile method. It's an action and passing argument to it is not possible. Just remove the "file" argument.

Filter a model's attributes before outputting as json

I need to output my model as json and everything is going fine. However, some of the attributes need to be 'beautified' by filtering them through some helper methods, such as number_to_human_size. How would I go about doing this?
In other words, say that I have an attribute named bytes and I want to pass it through number_to_human_size and have that result be output to json.
I would also like to 'trim' what gets output as json if that's possible, since I only need some of the attributes. Is this possible? Can someone please give me an example? I would really appreciate it.
Preliminary search results hint at something regarding as_json, but I can't find a tangible example pertaining to my situation. If this is really the solution, I would really appreciate an example.
Research: It seems I can use to_json's options to explicitly state which attributes I want, but I'm still in need of figuring out how to 'beautify' or 'filter' certain attributes by passing them through a helper before they're output as json.
Would I create a partial for a single json model, so _model.json.erb, and then create another one for the action I'm using, and within that simply render the partial with the collection of objects? Seems like a bunch of hoops to jump through. I'm wondering if there's a more direct/raw way of altering the json representation of a model.
Your model can override the as_json method, which Rails uses when rendering json:
# class.rb
include ActionView::Helpers::NumberHelper
class Item < ActiveRecord::Base
def as_json(options={})
{ :state => state, # just use the attribute when no helper is needed
:downloaded => number_to_human_size(downloaded)
}
end
end
Now you can call render :json in the controller:
#items = Item.all
# ... etc ...
format.json { render :json => #items }
Rails will call Item.as_json for each member of #items and return a JSON-encoded array.
I figured out a solution to this problem, but I don't know if it's the best. I would appreciate insight.
#items = Item.all
#response = []
#items.each do |item|
#response << {
:state => item.state,
:lock_status => item.lock_status,
:downloaded => ActionController::Base.helpers.number_to_human_size(item.downloaded),
:uploaded => ActionController::Base.helpers.number_to_human_size(item.uploaded),
:percent_complete => item.percent_complete,
:down_rate => ActionController::Base.helpers.number_to_human_size(item.down_rate),
:up_rate => ActionController::Base.helpers.number_to_human_size(item.up_rate),
:eta => item.eta
}
end
respond_to do |format|
format.json { render :json => #response }
end
Basically I construct a hash on the fly with the values I want and then render that instead. It's working, but like I said, I'm not sure if it's the best way.

Inheriting and routing a custom action from ApplicationController in Rails

I am using Rails 2.3.2 but I'm sure this applies to newer versions as well. I would like to define a custom action in ApplicationController. However, I don't want to add a custom route to every single controller subclass which uses this action. Is there an easy way to do this?
My first inclination was to just route directly to the ApplicationController, since the method does not need to be overridden by any subclasses. But I don't think Rails lets you route to the ApplicationController anymore.
Somebody else suggested something like this:
map.connect ":controller/:action", :controller => my_regex, :action => my_regex
But I'm wondering if this has the potential of conflicting with or overriding other routes? Or if there's generally a better way? Thanks!
I don't think this is a case of modifying ApplicationController, but of monkey-patching the code in ActionDispatch::Routing to include the new actions you want. This seems like a pretty crazy thing to do in the scheme of things as there's no standard way to augment or extend the usual REST actions. I hope you've got a good reason for doing this.
In looking through the code you can see where the default actions are defined, and you might be able to introduce a new one. Rails 3 has a slightly different structure but the idea is the same:
class ActionDispatch::Routing::Mapper::Resources::Resource
ENHANCED_DEFAULT_ACTIONS = DEFAULT_ACTIONS + [ :myaction ]
def self.default_actions
ENHANCED_DEFAULT_ACTIONS
end
end
You'll have to modify ActionDispatch::Routing::Mapper::Resources#resources to behave differently, too, but you didn't specify if you're talking about a collection, new or member type of action so you'll have to just copy and modify the routine to behave as you want.
if you are declaring this controller as a resource such as map.resource then you will have to use the default actions or create your own by adding a member or collection to that resource.
map.resources :post, :member => {:update_live_boolean => :post }, :collection => {:get_all_live_posts => :get}
Otherwise if you have the old routing format and are not using REST
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
Then all you need to do to link to a custom controller is provide the :controller' and:action/:id` variables when needed
<%= link_to "New Custom Controller", {:controller => "new_custom_controller", :action => "index"%>
This is the part of your post that concerns me:
I don't want to add a custom route to
every single controller subclass which
uses this action.
The rails community is rightly getting more and more careful about not over-defining needless routes. It's getting more common to see things like this:
map.resources :comments, :only => [:new, :create]
In the above example, only the new and create routes are generated. It's better security, and cleaner routing. While I'm not directly answering your question of how to make a new route available to every resource, I'm saying that rails best practices would discourage it. Add the custom route only to the resources that will actually use it.
In the end I decided to consider my js_form_builder a resource of its own, so I have a controller that will deliver it. The controller takes optional resource_name and id parameters. If provided, I can instantiate an object like so:
#object = params[:resource_name].classify.constantize.find(params[:id])
Then I simply send down a js.erb template that has all my js_form_builder goodness contained within. If #object has been instantiated, then I can create a form_for #object, then loop through its attributes and create methods on the javascript form builder object that will return inputs for each attribute, using Rails FormBuilder tags to create them.
For example:
window.FormBuilder = function() {
var builder = {};
builder.form = function() {
var js = "";
js += '<%= form_for #object do |f| %>';
<% #object.attributes.each do |name, val| %>
var methodName = '<%= name.camelize(:lower) %>';
<% if val.class == String %>
builder[methodName] = $('<%= f.text_field name.to_sym %>');
<% end %>
<% if val.class == TrueClass || val.class == FalseClass %>
builder[methodName] = $('<%= f.check_box name.to_sym %> <%= f.label name.to_sym %>');
<% end %>
<% end %>
js += '<% end %>';
return $(js);
};
builder.newForm = function() {
var js = "";
js += '<%= form_for #object.class.new do |f| %>';
js += '<% end %>';
}
return builder;
}
I'm not currently sure how useful these inputs will be, since I can't think of a scenario where I wouldn't just use html.erb for these. But it was sure fun making it work! :)

Resources