85104
85104
https://ebookultra.com/download/crafting-rails-4-applications-expert-
practices-for-everyday-rails-development-2nd-edition-jose-valim/
https://ebookultra.com/download/ruby-on-rails-tutorial-learn-web-
development-with-rails-3rd-edition-michael-hartl/
https://ebookultra.com/download/restful-rails-development-building-
open-applications-and-services-1st-edition-silvia-puglisi/
https://ebookultra.com/download/agile-web-development-with-
rails-5-1st-edition-sam-ruby/
https://ebookultra.com/download/ruby-on-rails-for-dummies-1st-edition-
burd/
Developing Facebook Platform Applications with Rails 1st
Edition Michael J. Mangino
https://ebookultra.com/download/developing-facebook-platform-
applications-with-rails-1st-edition-michael-j-mangino/
https://ebookultra.com/download/agile-web-development-with-rails-4th-
edition-beta-10-version-sam-ruby/
https://ebookultra.com/download/build-your-own-ruby-on-rails-web-
applications-1st-edition-patrick-lenz/
https://ebookultra.com/download/rails-recipes-1st-edition-chad-fowler/
https://ebookultra.com/download/enterprise-rails-1st-edition-dan-chak/
Crafting Rails 4 applications expert practices for
everyday Rails development 2nd Edition José Valim
Digital Instant Download
Author(s): José Valim
ISBN(s): 9781937785550, 1937785556
Edition: 2
File Details: PDF, 3.34 MB
Year: 2013
Language: english
ß
Under Construction: The book you’re reading is still under
development. As part of our Beta book program, we’re releasing
this copy well before a normal book would be released. That
way you’re able to get this content a couple of months before
it’s available in finished form, and we’ll get feedback to make
the book even better. The idea is that everyone wins!
Be warned: The book has not had a full technical edit, so it will contain errors.
It has not been copyedited, so it will be full of typos, spelling mistakes, and the
occasional creative piece of grammar. And there’s been no effort spent doing
layout, so you’ll find bad page breaks, over-long code lines, incorrect hyphen-
ation, and all the other ugly things that you wouldn’t expect to see in a finished
book. It also doesn't have an index. We can’t be held liable if you use this book
to try to create a spiffy application and you somehow end up with a strangely
shaped farm implement instead. Despite all this, we think you’ll enjoy it!
Send us your feedback: In the meantime, we’d appreciate you sending us your
feedback on this book at pragprog.com/titles/jvrails2/errata, or by using the links
at the bottom of each page.
Jose Valim
Preface . . . . . . . . . . . . . . vii
In addition, all the code has been updated to support Rails 4.0 RC2.
All outstanding errata has been addressed. Thanks to everyone who submitted
items that needed fixing. Keep them coming!
Some developers felt that using DataMapper instead of Active Record was a
better fit. Other developers turned to MongoDB and other nonrelational
databases but still wanted to use their favorite web framework. Then there
were those developers who preferred RSpec to Test::Unit. These developers
hacked, cobbled, or monkey-patched solutions together to accomplish their
goals because previous versions of Rails did not provide a solid API or the
modularity required to make these changes in a clean, maintainable fashion.
With time, Rails started to listen to those developers and after years, the end
result is a robust and wide set of plugin APIs, targetted to developers that
want to customize their wokflows, replace whole components, bending Rails
to their needs without messy hacks.
This book guides you through these plugin APIs through practical examples.
In each chapter, we will use test-driven development to build a Rails plugin
or application that covers those APIs and how they fit in the Rails architecture.
By the time you finish this book, you will understand Rails better and be
more productive while writing more modular and faster Rails applications.
render() method works so you can customize it to accept custom options, such
as :pdf.
Rails Versions
All projects in Crafting Rails Applications were developed and tested against
Rails 4.0.0. Future stable releases, like Rails 4.0.1, 4.0.2, and so forth, should
be suitable as well. You can check your Rails version with the following
command:
rails -v
And you can use gem install to get the most appropriate version:
gem install rails -v 4.0.0
This book also has excerpts from Rails’ source code. All these excerpts were
extracted from Rails 4.0.0.
Most of the APIs described in this book should remain compatible throughout
Rails releases. Very few of them changed since the release of the first edition
of this book.1.
1. http://www.pragprog.com/titles/jvrails/
2. http://rubyinstaller.org/downloads/
3. http://railsinstaller.org
render() to accept :pdf as an option with a behavior we will define. This chapter
starts a series of discussions about Rails’ rendering stack.
In Chapter 2, Building Models with Active Model, on page 17, we will take a
look at Active Model and its modules as we create an extension called Mail
Form that receives data through a form and sends it to a preconfigured email.
4. http://daringfireball.net/projects/markdown
a web interface. We will protect this translation interface using Devise5 and
show Capybara’s6 flexibility to write integration tests for different browsers.
Online Resources
The book’s website7 has links to an interactive discussion forum as well as errata
for the book. You’ll also find the source code for all the projects we build. Readers
of the ebook can click the gray box above the code excerpts to download that
snippet directly.
If you find a mistake, please create an entry on the errata page so we can address
it. If you have an electronic copy of this book, there are links in the footer of each
page that you can use to easily submit errata to us.
Let’s get started by creating a Rails plugin that customizes the render() method so
we can learn how Rails’ rendering stack works.
José Valim
[email protected]
April 2013
5. https://github.com/plataformatec/devise
6. https://github.com/jnicklas/capybara
7. http://www.pragprog.com/titles/jvrails2/
CHAPTER 1
To achieve this, Rails provides an API that we can use to create our own
renderers. We’ll explore this API as we modify the render() method to accept
1
:pdf as an option and return a PDF created with Prawn, a tiny, fast, and
nimble PDF writer library for Ruby.
As most chapters in this book, we’ll use the rails plugin generator to create a
plugin that extends Rails capabilities. Let’s get started!
1. https://github.com/prawnpdf/prawn
The generator finishes by running bundle install, which uses Bundler2 to install
all dependencies required by our project. With everything set up, let’s explore
the generated files.
pdf_renderer.gemspec
The pdf_renderer.gemspec provides a basic gem specification. The specification
declares the gem authors, its version, its dependencies, the gem source files
and more. This allows us to easily bundle our plugin into a Ruby Gem, making
it easy for us to share our code across different Rails applications.
Notice the gem has the same name as the file inside the lib directory, which
is pdf_renderer. By following this convention, whenever you declare this gem in
a Rails application’s Gemfile, the file at lib/pdf_renderer.rb will be automatically
required. For now, this file contains only a definition for the PdfRenderer module.
2. http://gembundler.com/
Finally, notice that our gemspec does not contain a explicit version. Instead,
the version is defined in lib/pdf_renderer/version.rb which is referenced in the
gemspec as PdfRenderer::VERSION. This is a common practice in Ruby Gems.
Gemfile
In a Rails application, the Gemfile is used to list all sorts of dependencies, no
matter if it is a development, test or production dependency. However, as our
plugin already has a gemspec to list dependencies, the Gemfile simply reuses
the gemspec dependencies. The Gemfile may eventually contain extra dependen-
cies which you find convenient to use during development, like the debugger
or the excellent pry3 gems.
Rakefile
The Rakefile provides basic tasks to run the test suite, generate documentation
and release our gem to the public. We can get the full list by executing rake -
T at pdf_renderer’s root:
$ rake -T
rake build # Build pdf_renderer-0.0.1.gem into the pkg directory
rake clobber_rdoc # Remove RDoc HTML files
rake install # Build and install pdf_renderer-0.0.1.gem into system gems
rake rdoc # Build RDoc HTML files
rake release # Create tag v0.0.1 and build and push pdf_renderer...
rake rerdoc # Rebuild RDoc HTML files
rake test # Run tests
The config/boot.rb file has only one responsibility: to configure our application’s
load paths. The config/application.rb file should then load all required dependencies
and configure the application, which is initialized in config/environment.rb.
3. http://pryrepl.org/
The boot file generated by rails plugin can be found at test/dummy/config/boot.rb and
it is similar to the application one, the only difference is that it needs to point
to the Gemfile at the root of the pdf_renderer plugin. It also explicitly adds the
plugin’s lib directory to Ruby’s load path, making our plugin available inside
the dummy application:
pdf_renderer/1_prawn/test/dummy/config/boot.rb
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
The boot file delegates the responsibility of setting up dependencies and their
load path to Bundler. The test/dummy/config/application.rb is a stripped down
version of the config/application.rb found in Rails applications:
pdf_renderer/1_prawn/test/dummy/config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(*Rails.groups)
require "pdf_renderer"
module Dummy
class Application < Rails::Application
# ...
end
end
Running Tests
rails plugin generates by default one sanity test for our plugin. Let’s run our
tests and see them pass with the following:
$ rake test
# Running tests:
pdf_renderer/1_prawn/test/pdf_renderer_test.rb
require 'test_helper'
Finally, note that our test file requires test/test_helper.rb, which is the file
responsible for loading our application and configuring our testing environ-
ment. With our plugin skeleton created and a green test suite, we can start
writing our first custom renderer.
if options[:callback].present?
self.content_type ||= Mime::JS
"#{options[:callback]}(#{json})"
else
self.content_type ||= Mime::JSON
json
end
end
it will invoke the block defined as the :json renderer. The local variable json
inside the block points to the @post object, and the other options passed to
render() will be available in the options variable. In this case, since the method
was called without any extra options, it’s an empty hash.
In the following sections, we want to add a :pdf renderer that creates a PDF
document from a given template and sends it to the client with the appropriate
headers. The value given to the :pdf option should be the name of the file to
be sent.
Although Rails knows how to render templates and send files to the client, it
does not know how to handle PDF files. For this, let’s use Prawn.
Next, let’s ask bundler to install our new dependency and test it via interactive
Ruby:
$ bundle install
$ irb
pdf = Prawn::Document.new
pdf.text("A PDF in four lines of code")
pdf.render_file("sample.pdf")
Exit irb, and you can see a PDF file in the directory in which you started the
irb session. Prawn provides its own syntax to create PDFs, and although this
gives us a flexible API, the drawback is that it cannot create PDF from HTML
files.
4. https://github.com/prawnpdf/prawn
Code in Action
Let’s write some tests before we dive into the code. Since we have a dummy
application at test/dummy, we can create controllers as in an actual Rails
application and use them to test the complete request stack. Let’s name the
controller used in our tests HomeController and add the following contents:
pdf_renderer/1_prawn/test/dummy/app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
respond_to do |format|
format.html
format.pdf { render pdf: "contents" }
end
end
end
Finally, let’s write an integration test that verifies a PDF is in fact being
returned when we access /home.pdf:
pdf_renderer/1_prawn/test/integration/pdf_delivery_test.rb
require "test_helper"
The test uses the response headers to assert that a binary-encoded PDF file
was sent as an attachment, including the expected filename. Although we
cannot assert anything about the PDF body since it’s encoded, we can at least
assert that it has the string PDF in it. Let’s run our test with rake test and
watch it fail:
1) Failure:
test_pdf_request_sends_a_pdf_as_file(PdfDeliveryTest):
Expected /PDF/ to match "This template is rendered with Prawn.\n".
The test fails as expected. Since we haven’t taught Rails how to handle the
:pdf option in render, it is simply rendering the template without wrapping it
in a PDF. We can make the test pass by implementing our renderer in just a
few lines of code inside lib/pdf_renderer.rb:
pdf_renderer/1_prawn/lib/pdf_renderer.rb
require "prawn"
ActionController::Renderers.add :pdf do |filename, options|
pdf = Prawn::Document.new
pdf.text render_to_string(options)
send_data(pdf.render, filename: "#{filename}.pdf",
disposition: "attachment")
end
And that’s it! In this code block, we create a new PDF document, add some
text to it, and send the PDF as an attachment using the send_data() method
available in Rails. We can now run the tests and watch them pass. You can
also go to test/dummy, start the server with rails server, and test it by yourself by
accessing http://localhost:3000/home.pdf.
Even though our test passes, there is still some explaining to do. First of all,
observe that we did not, at any point, set the Content-Type to application/pdf. How
did Rails know which content type to set in our response?
The content type was set correctly because Rails ships with a set of registed
formats and mime types:
rails/actionpack/lib/action_dispatch/http/mime_types.rb
Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
Mime::Type.register "text/plain", :text, [], %w(txt)
Mime::Type.register "text/javascript", :js,
%w(application/javascript application/x-javascript)
Mime::Type.register "text/css", :css
Mime::Type.register "text/calendar", :ics
Mime::Type.register "text/csv", :csv
Notice how the PDF format is defined with its respective content type. When
we requested the /home.pdf URL, Rails retrieved the pdf format from the URL,
verified it matched with the format.pdf block defined in HomeController#index and
proceeded to set the proper content type before invoking the block which
called render.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebookultra.com