This website uses cookies to better the user experience of its visitors. Where applicable, this website uses a cookie control system, allowing users to allow or disallow the use of cookies on their computer/device on their first visit to the website. This complies with recent legislative requirements for websites to obtain explicit consent from users before leaving behind or reading files such as cookies on a user’s computer/device. To learn more click Cookie Policy.

Privacy preference center

Cookies are small files saved to a user’s computer/device hard drive that track, save, and store information about the user’s interactions and website use. They allow a website, through its server, to provide users with a tailored experience within the site. Users are advised to take necessary steps within their web browser security settings to block all cookies from this website and its external serving vendors if they wish to deny the use and saving of cookies from this website to their computer’s/device’s hard drive. To learn more click Cookie Policy.

Manage consent preferences

These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
Cookies list
Name _rg_session
Provider rubygarage.org
Retention period 2 days
Type First party
Category Necessary
Description The website session cookie is set by the server to maintain the user's session state across different pages of the website. This cookie is essential for functionalities such as login persistence, ensuring a seamless and consistent user experience. The session cookie does not store personal data and is typically deleted when the browser is closed, enhancing privacy and security.
Name m
Provider m.stripe.com
Retention period 1 year 1 month
Type Third party
Category Necessary
Description The m cookie is set by Stripe and is used to help assess the risk associated with attempted transactions on the website. This cookie plays a critical role in fraud detection by identifying and analyzing patterns of behavior to distinguish between legitimate users and potentially fraudulent activity. It enhances the security of online transactions, ensuring that only authorized payments are processed while minimizing the risk of fraud.
Name __cf_bm
Provider .pipedrive.com
Retention period 1 hour
Type Third party
Category Necessary
Description The __cf_bm cookie is set by Cloudflare to support Cloudflare Bot Management. This cookie helps to identify and filter requests from bots, enhancing the security and performance of the website. By distinguishing between legitimate users and automated traffic, it ensures that the site remains protected from malicious bots and potential attacks. This functionality is crucial for maintaining the integrity and reliability of the site's operations.
Name _GRECAPTCHA
Provider .recaptcha.net
Retention period 6 months
Type Third party
Category Necessary
Description The _GRECAPTCHA cookie is set by Google reCAPTCHA to ensure that interactions with the website are from legitimate human users and not automated bots. This cookie helps protect forms, login pages, and other interactive elements from spam and abuse by analyzing user behavior. It is essential for the proper functioning of reCAPTCHA, providing a critical layer of security to maintain the integrity and reliability of the site's interactive features.
Name __cf_bm
Provider .calendly.com
Retention period 30 minutes
Type Third party
Category Necessary
Description The __cf_bm cookie is set by Cloudflare to distinguish between humans and bots. This cookie is beneficial for the website as it helps in making valid reports on the use of the website. By identifying and managing automated traffic, it ensures that analytics and performance metrics accurately reflect human user interactions, thereby enhancing site security and performance.
Name __cfruid
Provider .calendly.com
Retention period During session
Type Third party
Category Necessary
Description The __cfruid cookie is associated with websites using Cloudflare services. This cookie is used to identify trusted web traffic and enhance security. It helps Cloudflare manage and filter legitimate traffic from potentially harmful requests, thereby protecting the website from malicious activities such as DDoS attacks and ensuring reliable performance for genuine users.
Name OptanonConsent
Provider .calendly.com
Retention period 1 year
Type Third party
Category Necessary
Description The OptanonConsent cookie determines whether the visitor has accepted the cookie consent box, ensuring that the consent box will not be presented again upon re-entry to the site. This cookie helps maintain the user's consent preferences and compliance with privacy regulations by storing information about the categories of cookies the user has consented to and preventing unnecessary repetition of consent requests.
Name OptanonAlertBoxClosed
Provider .calendly.com
Retention period 1 year
Type Third party
Category Necessary
Description The OptanonAlertBoxClosed cookie is set after visitors have seen a cookie information notice and, in some cases, only when they actively close the notice. It ensures that the cookie consent message is not shown again to the user, enhancing the user experience by preventing repetitive notifications. This cookie helps manage user preferences and ensures compliance with privacy regulations by recording when the notice has been acknowledged.
Name referrer_user_id
Provider .calendly.com
Retention period 14 days
Type Third party
Category Necessary
Description The referrer_user_id cookie is set by Calendly to support the booking functionality on the website. This cookie helps track the source of referrals to the booking page, enabling Calendly to attribute bookings accurately and enhance the user experience by streamlining the scheduling process. It assists in managing user sessions and preferences during the booking workflow, ensuring efficient and reliable operation.
Name _calendly_session
Provider .calendly.com
Retention period 21 days
Type Third party
Category Necessary
Description The _calendly_session cookie is set by Calendly, a meeting scheduling tool, to enable the meeting scheduler to function within the website. This cookie facilitates the scheduling process by maintaining session information, allowing visitors to book meetings and add events to their calendars seamlessly. It ensures that the scheduling workflow operates smoothly, providing a consistent and reliable user experience.
Name _gat_UA-*
Provider rubygarage.org
Retention period 1 minute
Type First party
Category Analytics
Description The _gat_UA-* cookie is a pattern type cookie set by Google Analytics, where the pattern element in the name contains the unique identity number of the Google Analytics account or website it relates to. This cookie is a variation of the _gat cookie and is used to throttle the request rate, limiting the amount of data collected by Google Analytics on high traffic websites. It helps manage the volume of data recorded, ensuring efficient performance and accurate analytics reporting.
Name _ga
Provider rubygarage.org
Retention period 1 year 1 month 4 days
Type First party
Category Analytics
Description The _ga cookie is set by Google Analytics to calculate visitor, session, and campaign data for the site's analytics reports. It helps track how users interact with the website, providing insights into site usage and performance.
Name _ga_*
Provider rubygarage.org
Retention period 1 year 1 month 4 days
Type First party
Category Analytics
Description The _ga_* cookie is set by Google Analytics to store and count page views on the website. This cookie helps track the number of visits and interactions with the website, providing valuable data for performance and user behavior analysis. It belongs to the analytics category and plays a crucial role in generating detailed usage reports for site optimization.
Name _gid
Provider rubygarage.org
Retention period 1 day
Type First party
Category Analytics
Description The _gid cookie is set by Google Analytics to store information about how visitors use a website and to create an analytics report on the website's performance. This cookie collects data on visitor behavior, including pages visited, duration of the visit, and interactions with the website, helping site owners understand and improve user experience. It is part of the analytics category and typically expires after 24 hours.
Name _dc_gtm_UA-*
Provider rubygarage.org
Retention period 1 minute
Type First party
Category Analytics
Description The _dc_gtm_UA-* cookie is set by Google Analytics to help load the Google Analytics script tag via Google Tag Manager. This cookie facilitates the efficient loading of analytics tools, ensuring that data on user behavior and website performance is accurately collected and reported. It is categorized under analytics and assists in the seamless integration and functioning of Google Analytics on the website.

Ruby on Rails 4 And Symfony 2 Comparison - Testing, Modularity, Dependencies, and Scalability

  • 14727 views
  • 10 minutes
Vlad K.

Vlad K.

PHP Developer

Sviatoslav A.

Sviatoslav A.

Copywriter

Share

In this article we’ll consider four aspects of the Ruby on Rails 4 and Symfony 2 frameworks. When building commercial products with these frameworks, we have to extend their functionality with plugins, split applications into modules, and test and scale products. Thus, we will focus on how Rails 4 and Symfony 2 manage dependencies, modularity, testing, and scaling.

Dependency management

Bundler is itself a Ruby gem, but is the most common solution for installing other gems and managing dependencies between gems and Rails applications. Bundler downloads and installs required gems into your system from RubyGems.org and then manages dependencies among them.

If you work with several projects simultaneously, you must have separate Gemfiles for each project. Specify the gems you want to include in your app – and their dependencies – in the Gemfile, and then run the following command:

$ bundle install

This will automatically download and install the libraries you specified, and Bundler will trigger an alert if there are conflicts between libraries. For example, if a gem requires the latest version of another gem to work normally, Bundler will notify you. Ruby’s Bundler also provides other important commands, for example, a command to generate a new standard Gemfile for a project.

Ruby on Rails And Symfony comparison

Composer is similar to Bundler, and is used with Symfony 2 and several other PHP frameworks. Composer’s creators were inspired by Ruby’s Bundler, so their approach to resolving dependencies in PHP projects is very similar. Specify required dependencies in the composer.json file and then run the following command:

php composer.phar install

Composer differs from Bundler in a very important respect, though, bringing PHP libraries and Symfony bundles into a specific project, not into the entire system. This helps define independent environments for particular projects. With Bundler, you may need to install several dozen gems that aren’t used in one project but are necessary for others. This usually leads to conflicts, which you have to resolve by removing old dependencies, by using similar libraries or by implementing monkey patches.

In short, Composer and Bundler are both great tools that can update libraries and handle other package-related operations with ease. That’s all you need when resolving dependencies in your projects!

Modularity

Both Ruby on Rails 4 and Symfony 2 allow you to architect web apps from multiple components. This helps you build apps more quickly and replace irrelevant components more easily than if all your code is in one place. Components in Ruby on Rails are called engines, while Symfony calls them bundles.

Ruby on Rails And Symfony modularity

You can think of engines as ordinary Rails plugins, although engines are more like small applications (read: more advanced than plugins). But in most respects, Rails plugins and engines have similar structures, such as the lib directory structure, and share common features.

When building a Rails app, you can take advantage of many existing engines. Here’s the top four Rails engines that we use at RubyGarage:

  • Spree, an ecommerce engine for delivering web storefronts;
  • Devise, an engine providing authentication for its parent applications;
  • Forem, an engine for forum functionality;
  • RefineryCMS, a Content Management System engine.

Many Rails engines and gems are located in the aforementioned RubyGems.org catalog, which currently offers more than 7,700 libraries.

Bundles in Symfony are also like ordinary plugins. When creating new bundles or using ready solutions in your Symfony 2 application, you have to encapsulate them using namespaces. Just add a bundle class to a namespace like this: namespace MyProject\MyFirstBundle;. This way you avoid irritating conflicts between bundles with identical names.

One of the biggest Symfony 2 bundle sources is KnpBundles.com, which currently offers almost 3,000 third-party solutions. In addition to KnpBundles, you can import any third-party PHP library to your web app from Packagist.org, which offers over 94,000 bundles.

Here’s a list of our favorite Symfony bundles that we install in almost every project:

  • FriendsOfSymfony/FOSUserBundle;
  • FriendsOfSymfony/FOSRestBundle;
  • DoctrineBundle;
  • AsseticBundle;
  • SwiftmailerBundle;
  • MonologBundle;
  • DistributionBundle.

The bottom line is that both the Ruby on Rails and Symfony 2 frameworks allow you to create component-based applications. Many developers have already built tons of libraries to help you solve common development tasks. So if you’re looking for standard functionality, chances are that you’ll find a suitable extension for your Rails or Symfony app.

Testing

To avoid regressions (when new bugs appear after implementing new functionality) and to find existing bugs as early as possible, you have to cover your code with automated tests. If bugs are found during the production stage, this usually demands much more time and effort to fix them than if they were found when the code was initially written.

Both Ruby on Rails and Symfony can benefit from the Test Pyramid – a concept by Mike Cohn – that defines the following priority for tests:

Ruby on Rails And Symfony Pyramid Testing

Unit tests are easier to implement and harder to break, so use them as much as is practical. These tests check an application’s business logic code. Functional tests check how individual software modules act on their own. Acceptance tests are the most time-consuming and unreliable, requiring you to compile and check complete application builds. Therefore, it’s better to cut down on the number of acceptance tests as much as possible.

Ruby on Rails offers a built-in framework for testing called Minitest. However, the majority of Ruby developers rely on RSpec. RSpec boasts great code readability and a large community that supports many additional extensions.

Here’s an example of a unit test written in RSpec:

We can also use RSpec to write functional tests that check if Rails controllers call required services correctly and respond with necessary data. Functional tests are especially important when you need to check controllers that are APIs for other clients (such as a mobile app).

Acceptance tests for Rails check an application’s functionality from a user’s point of view. For instance, a test can fill in a registration form, submit the form, and check the response against an expected result. We use RSpec to write a scenario, and then Poltergeist or a Webkit web driver to run an acceptance test in a browser.

You can also use the Gherkin language to write such test scenarios. Gherkin allows you to literally turn functionality requirements into Gherkin code and use them as test cases, usually written by a project manager.

Check out the following code to see an example scenario written in Gherkin:

Scenario: Post article by user

Given I signed up as user
When I write article "Justin Bieber"
And text of article is "is awesome"
And I post article
Then I should see "You have no access to post articles"

Now let’s talk about testing with Symfony 2. Symfony doesn’t come with its own testing framework. Instead, this PHP framework benefits from a third-party solution called PHPUnit, and even offers an official testing guide based on this solution.

PHPUnit is a PHP testing framework introduced in 2004. Later on, the Codeception framework was also introduced on top of PHPUnit to help support the behavior-driven development approach, when an application’s code is covered with tests even before it’s written.

The following code excerpt is a unit test written for PHPUnit:

You can find other testing code on Symfony/Testing to learn more details.

Acceptance tests for Symfony 2 can be performed with Selenium Server and Selenium WebDriver, which is managed by PHPUnit tests with the help of the php-webdriver library.

At RubyGarage, we regularly practice the Continuous Integration approach with Ruby on Rails 4 and Symfony 2. Continuous Integration means that new code is integrated into the repository several times a day and is verified by automated tests – and then manual code review – before going into a production build.

As you can see, there are advanced tools for both Rails 4 and Symfony 2 to help you test your apps. We would also like to mention JavaScript (JS) testing, however, as all modern apps with front end are rarely written without JS. Therefore, you must properly test the JS code, and Jasmine is handy for this. The Jasmine framework can be used to write unit and functional tests, and is very similar to RSpec in terms of syntax.

Scalability

We should note that a framework’s scalability rarely correlates with an application’s ability to scale. In this section, we will review the practices you have to use in order to build scalable solutions with both Symfony and Ruby on Rails.

You can scale Rails 4 and Symfony 2 apps either vertically (by increasing server performance) or horizontally (by increasing the number of servers: application servers, database servers, caching servers, tasks servers, or CDN servers).

Web developers usually apply a complex of infrastructure improvements and configuration modifications to launch an application on distributed nodes. Here’s a general list of solutions and tools that we frequently use to scale Symfony 2 and Rails 4 apps:

  • A three-tier client-server architecture (instead of a single-tier architecture);
  • Redis for storing user sessions, DQL cache, and Doctrine mapping;
  • MongoDB and ElasticSearch for storing aggregates of data;
  • RabbitMQ to perform asynchronous operations through queues;
  • Varnish to cache static resources and low dynamics HTML pages;
  • Monolog and ELK stack for incident analytics;
  • Hosting app nodes on Amazon Web Services (AWS);
  • Assetic Bundle to minify and obfuscate JS and CSS files.

If we use all the solutions just listed, we can make Symfony 2 apps run over one billion requests per week with 30ms response time.

We would like to add that, although many Ruby on Rails applications have a monolithic structure, it’s easy to find a bottleneck in an app and implement that part as a standalone service. You can then further scale this service, which is a better option than increasing the number of app instances running simultaneously. This very same approach to scaling an application – which is called microservices – can be used with Symfony 2.

When using microservices, you can also implement some business logic in a lower-level language such as Go, Java, Scala, or C++. This is useful when you need to run unusually complex computations. It’s easy to integrate such a solution into your Ruby on Rails or Symfony application.

Hosting your Rails or Symfony application on Amazon Web Services (AWS) is one of the best options for scaling apps – as they’ll scale automatically. That is, additional servers will be provisioned to increase an app’s performance when required.

Ultimately, the scalability of an app built with either Symfony 2 or Ruby on Rails 4 is dependent on the app architecture you’ve engineered. Build a scalable architecture with either of these frameworks from the very beginning, and the app will scale in the future when necessary. (Note that making an architecture scalable means making smart decisions about how to link different app modules.)


As you can see, although these two frameworks – Ruby on Rails 4 and Symfony 2 – are written in completely different languages, they share very similar approaches to dependency management and modularity. Both offer advanced testing tools and allow almost endless scaling potential as long as your application is well architected. Because these frameworks are equally capable, the choice of which to use is really a matter of your personal preference.

CONTENTS

Authors:

Vlad K.

Vlad K.

PHP Developer

Sviatoslav A.

Sviatoslav A.

Copywriter

Rate this article!

Nay
So-so
Not bad
Good
Wow
2 rating, average 5 out of 5

Share article with

Comments (1)
John Williams
John Williams about 3 years ago
Your excellence in the technological field is worth applause. We want to collaborate with startups to generate a new market phase and improve the future experience.
Reply

Subscribe via email and know it all first!