Formatting XML from Nokogiri - ruby-on-rails

I'm using Nokogiri to create XML:
class Output
require 'nokogiri'
def self.xml
data = IncomingData.all
builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
data.each do |o|
xml.id {
xml.account_id_ o.account_id
xml.date_ o.date
xml.account_type o.account_type
xml.activity o.activity
xml.position o.position
xml.security o.security
}
end
}
end
builder.to_xml
end
end
This is my controller action:
respond_to do |format|
format.xml { render xml: Output.xml }
end
which works nicely:
But I need to output it with indentation like:
account_id
date
account_type
How I can do it?
ruby -v returns:
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin14.0]
nokogiri --version returns:
# Nokogiri (1.6.7)

Just create valid hash, and add to him .to_xml method

Related

Rails API active model serializer root node not working

I have a rails 4.2.5 API app. For some reason, the JSON root node is not included in the response and I don't understand why.
curl http://localhost:3000/api/v1/category/science
returns
{"title":"science","sub_categories":34}%
instead of
{"category": {"title":"science","sub_categories":34}%}
The code:
controller
class Api::V1::CategoryController < ApplicationController
def show
category = params[:category] || "sports"
#category = Category.where(cat_title: category.capitalize).first
respond_to do |format|
format.json { render json: #category, serializer: CategorySerializer, root: "category" }
end
end
end
serializer
class CategorySerializer < ActiveModel::Serializer
attributes :title, :sub_categories
def title
URI::encode(object.cat_title.force_encoding("ISO-8859-1").encode("utf-8", replace: nil).downcase.tr(" ", "_"))
end
def sub_categories
object.cat_subcats
end
end
have a look into your initializers, this should be commented out in wrap_paramters.rb:
# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = true
# end
Rails 5.0.0.1
Using ActiveMovelSerializers (0.10.2) you just need to add an initializer:
app/config/initializers/json_api.rb
require 'active_model_serializers/register_jsonapi_renderer'
ActiveModelSerializers.config.adapter = :json_api

uninitialized constant Prawn::FLOAT_PRECISION error showing while using prawn

I took the approach of Railscast episode 153 revised.
My controller is
class AdminsController < ApplicationController
def index
#examples = Example.all
respond_to do |format|
format.html
format.csv { send_data #examples.to_csv }
format.xls { send_data #examples.to_csv }
format.pdf do
pdf = DownloadPdf.new(#examples)
send_data pdf.render, filename: 'generate_table.pdf',
type: 'application/pdf', disposition: "inline"
end
end
end
end
and my download_pdf.rb file is
class DownloadPdf < Prawn::Document#make_table
require 'prawn/table'
def initialize(example)
super()
#examples = example
line_items
end
def line_items
image "#{Rails.root}/app/assets/images/logo.png"
table [[1,2],[3,4]]
end
end
I am using gems
gem 'prawn', :git => "https://github.com/prawnpdf/prawn.git", :ref => '8028ca0cd2'
gem 'prawn-table', '~> 0.1.0'
Thanx in advance for helping.
TL;DR: Update prawn gem by adding this to your Gemfile: gem 'prawn' and running bundle install.
Longer answer: You are using an old version of Prawn - that ref you are using in your Gemfile refers to somewhere in 2013. prawn-table 0.1 is newer and requires a newer version of prawn. More precisely, it's using Prawn's ::FLOAT_PRECISION constant, which was added in this 2014's commit to Prawn.
Please use below on Gemfile
gem 'prawn'
and then remove Gemfile.lock
and then
bundle install
restart server
you can use round(2) like this..
val= 456.7890999999
val.round(2)
and Ans will be 456.79

Active Model XML serialization : undefined method `[]' for nil:NilClass

Originally from here, i'm posting a new thread to focus on my issue resolving around the "to_xml" method.
What i'm trying to do : make a conversion from a ruby Object (Whois::Record) to XML.
I am currently using ActiveModel but not ActiveRecord (eg previous thread for reasons)
Here is the relevant controller :
def lookup
domain = params[:domain]
#whois = Request.new
#whois.search(domain)
respond_to do |format|
if #whois != nil
format.html
format.json {render :json => #whois.body}
format.xml {render :xml => #whois}
else
format.html { render :new }
format.json { render json: #request.errors, status: :unprocessable_entity }
end
end
end
Please note that #whois is NOT a Whois::Record object, but a class that contains such object (in the body property)
And the view :
<% if #whois != nil %>
<%= #whois %>
<!--JSON-->
<%= #whois.body.to_json %>
<!--XML-->
<% byebug %>
<%= #whois.to_xml %>
<% end %>
Note that the to_json method works fine, so the fact that ruby throws a nilClass exception is quite weird.
Here is the stacktrace starting from to_xml :
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/xml_mini.rb:148:in _dasherize'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/xml_mini.rb:140:inrename_key'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/xml_mini.rb:119:in to_tag'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/core_ext/hash/conversions.rb:88:inblock (2 levels) in to_xml'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/core_ext/hash/conversions.rb:88:in each'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/core_ext/hash/conversions.rb:88:inblock in to_xml'
/home/nico/.rvmruby (2.1.3) gems/builder-3.2.2/lib/builder/xmlbase.rb:175:in call'
/home/nico/.rvmruby (2.1.3) gems/builder-3.2.2/lib/builder/xmlbase.rb:175:in_nested_structures'
/home/nico/.rvmruby (2.1.3) gems/builder-3.2.2/lib/builder/xmlbase.rb:68:in tag!'
/home/nico/.rvmruby (2.1.3) gems/activesupport-4.1.6/lib/active_support/core_ext/hash/conversions.rb:87:into_xml'
app/models/request.rb:26:in `to_xml'
Byebug gives me a lead as such :
to_xml > ActiveSupport::SafeBuffer::OutpuBuffer#safe_concat
153: def safe_concat(value)
=> 154: raise SafeConcatError unless html_safe?
155: original_concat(value)
156: end
note : html_safe? is set at 'true' here, and value equals "\t"
original_concat
File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 132
Alias to original_concat
def concat(value)
if !html_safe? || value.html_safe?
super(value)
else
super(ERB::Util.h(value))
end
end
And when i step over i come back to the to_xml method, that's throwing a tantrum about not having a class to call upon methhods. I would be grateful for any help, thanks.
Edit
Here is the class Request from my model :
#This is a generic class for checking Key authenticity and sending requests to the engine
#Furthermore, this class will contain the WHOIS response in body
include ActiveModel::Model
include ActiveModel::Serializers::JSON
include ActiveModel::Serializers::Xml
attr_accessor :body
def attributes
{body => nil}
end
def to_xml(options = {})
to_xml_opts = {:skip_types => true} # no type information, not such a great idea!
to_xml_opts.merge!(options.slice(:builder, :skip_instruct))
# a builder instance is provided when to_xml is called on a collection of instructors,
# in which case you would not want to have <?xml ...?> added to each item
to_xml_opts[:root] ||= "instructor"
self.attributes.to_xml(to_xml_opts)
end
def search(domain)
# since rails compiles the code before executing a search once,
# we have to catch niClass exceptions and such
if domain != ( nil && true && "" )
c = Whois::Client.new
self.body = c.lookup(domain)
end
end
I've used this as from what i've understood XML tries to define a type for each attribute, and has problems with named objects. Here's the thread about to_xml and objects in rails

PDFKit, TypeError "Can't convert hash to string"

I'm using PDFKit with it's Middlware to render HTML as PDF but it keeps having a TypeError when I try to go to localhost:3000/booklets/1.pdf
can't convert Hash into String
It says the error is in BookletsController#show. This is an excerpt from my booklets_controller.rb
def show
#booklet = Booklet.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.pdf {
html = render_to_string(:action => "show.html.erb", :formats => [:html])
kit = PDFKit.new(html)
send_data(kit.to_pdf, :filename => "booklet.pdf", :type => 'application/pdf')
return
}
end
end
environnment.rb
# Initialize the rails application
Ziin::Application.initialize!
Mime::Type.register "application/pdf", :pdf
excerpt from application.rb
require 'pdfkit'
config.middleware.use "PDFKit::Middleware"
PDFKit.configure do |config|
config.wkhtmltopdf = { :exe_path => '/usr/local/bin/wkhtmltopdf' }
end
The problem is the exec path you specify. I just replicated the problem on my own machine (ubuntu 12.04), and I fixed it by NOT using the gem install of wkhtmltopdf, which adds some version of wkhtmltopdf that doesn't work.
1.) Look here for how to install wkhtmltopdf (non-gem version)
https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF
2.) Remove 'wkhtmltopdf' from your gem file
3.) Find the wkhtmltopdf executable by doing 'which wkhtmltopdf'. Use the path that is returned in the exe_path declaratioin.
4.) Don't know if this next step matters, but I moved:
PDFKit.configure do |config|
config.wkhtmltopdf = { :exe_path => "#{PATH}"
end
into config/initializers/pdfkit.rb
also remove the gem by 'gem uninstall wkhtmltopdf'

cannot load such file - Nokogiri rails

I wrote a Ruby script in which I use Nokogiri.
For Rails I made this module in the lib/ directory:
require "net/http"
require "uri"
require 'nokogiri'
Module gk_CT
class CT
def getCT
uri = URI.parse("http://www.website.com")
CT = Net::HTTP.get_response(uri)
proc = Nokogiri::HTML(CT.body)
CTQ = Array.new
CTQ << proc.css('td')
end
end
In the controller I have:
require 'gk_CT'
def show
#CT= gk_CT::CT.getCT()
respond_to do |format|
format.html # show.html.erb
format.json { render json: #CT}
end
end
It always gives me the error:
cannot load such file -- nokogiri
and I have no idea why.
If the script is part of an actual Rails project, then you need to add Nokogiri to the Gemfile (with the line gem 'nokogiri'). If you're not in a Rails project or aren't using Bundler or some such weird thing, you'll still need to install the gem (gem install nokogiri).

Resources