Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Ruby on Rails Best Practices

Programming is an artJosh SoftwareSome Do’s and Don’ts to keep in mind while coding in ruby on railsIt is a commonly used phrase when talking about Rails best practices.It basically means placing most of the business logic, data manipulation, and validations within the models (fat models) while keeping the controllers focused on handling request/response and routing (skinny controllers).Your Model might look something like this:While your controller might look like:This can lead to more efficient and DRY (Don’t Repeat Yourself) code.Moreover, by separating concerns and adhering to the Single Responsibility Principle (SRP), you make your codebase more modular and easier to maintain.N+1 Problem is an infamous problem faced by many ORM using frameworks including rails.It arises when an application makes N additional queries to the database for a collection of records, where N is the number of initial records are retrieved.One solution to N+1 problem is Eager Loading, it uses a join or preload query to load associated records or data in advance, reducing the number of database queries and improving performance.In Rails, eager loading can be accomplished using the includes method or the preload method.Note that includes and preload have slightly different behaviors. includes performs a left outer join to load the associated data, which can help avoid the N+1 query problem. On the other hand, preload performs separate queries for each association and then associates the data in memory.This way if you want to parse all Post for each User, rails will use 2 queries (1 for user, 1 for posts) instead of calling additional query to fetch Post for each User.You can also use nested eager loading to fetch associations that have their own associations.However, you should be aware of what all should you eager load before including everything for a query especially for large dataset or multiple associated models.Here, we have eager loaded option_types, product_properties as well as images for Products, which has never been used.Therefore, by carefully considering your specific use case and evaluating the performance impact, you can decide whether or not to use eager loading.Rails has a powerful ORM(Object Relational Model) which it provides through ActiveRecord.Active Record includes validation features so data offered to the database can be validated before being accepted and persisted.Validations help maintain data integrity and prevent the storage of invalid or inconsistent data in your application’s database. To perform model validation in Rails, you typically define validation rules within your model classes using the validates method.Whereas Database validations are implemented using constraints defined at the database schema level. These validations are enforced by the database when attempting to save data. In Rails you can add database validations through migrations.So the question arises which is better Model Validations or Database Validations?Adding validations in the model saves you a database query (possibly across the network) that will essentially error out, and doing it in the database guarantees data consistency.IMO simple, data-related validation (such as field constraints) should be done in the database. Any validation that is following some business rules (such as email validation) should be done in the model.SQLi (SQL Injection) is a type of security vulnerability that occurs when an application fails to properly sanitize or validate user-supplied input before incorporating it into SQL queries.Since database is the core of any application, vulnerable sql queries can be very harmful for your application.If this particular line of code invoked with name = ‘fff’, the resulting query will be:But if it is set to “''OR 1='1'“:Instead use dynamic attribute based finderAn enum in Rails is a data type that represents a set of named values. The values of an enum are stored as integers in the database, but they can be accessed by name in Ruby code. This makes it easier to work with enums in your Rails application.Add an enum to an existing model is by adding an integer column to that table.Then in your model you can define the value of integers for that column, you can add enum for statuslike given belowOnce you have defined an enum, you can use it in your Ruby code like this:You can use _prefix (or suffix) in enum definition, so that all the helpers can be prefixed(or suffixed) by the column nameFilters are methods that are run before a controller action is executed.They can be used to perform common tasks, such as checking for authorization, setting up data, or redirecting the user to a different page.The authorize_user method is a private method that checks if the current user is authorized to access the index page. If the user is not authorized, the method redirects the user to the login page.The set_post method is a private method that sets the @post instance variable to the post with the given ID. This variable is then available in the show, update and destroy action.Hence, Filters are a powerful tool that can be used to improve the security and usability of your Rails application. They can also be used to simplify your code by centralizing common tasks.But keep in mind that Time.now returns a Time object representing the current time in the default system time zone. To get the current time in application’s configured time zone you have to use Time.zone.nowUnlike Time.now, which uses the default system time zone, Time.current takes into account the time zone configured for the Rails application. This ensures consistent and accurate time representation throughout the application, regardless of the server’s time zone settings.All Concerns, Services and Helpers are used to create reusable code for your models, controllers and views respectively.ConcernsIn Rails, Concerns are modules that encapsulate reusable code and behavior that can be included in multiple classes or modules. It extends ActiveSupport::Concern module.They help keep models focused and avoid excessive code duplication. Concerns are implemented using Ruby modules and included in classes using the include keyword.In the example above, the Trashable concern defines shared functionality related to trash entries. It is then included in the Songand Album model, allowing the model to leverage the methods defined within the concern.ServicesAs your application grows, you may begin to see domain/business logic littered across the models and the controller. Such logics do not belong to either the controller or the model, so they make the code difficult to re-use and maintain.Service objects are plain old Ruby objects (PORO’s) that do one thing .They encapsulate a set of business logic, moving it out of models and controllers and into a more focused setting.In above example, you can see we have a Create User service which creates and returns user with given parameters. This can be then reused in every controller where we need to create a new user.HelpersA helper is a method that is used in your Rails views to share reusable code. Helper methods are defined within modules called Helper Moduleand are automatically made available to the corresponding views.The above example demonstrates how the full_name helper method can be used to generate and display a user’s full name within the view. It can be used wherever we need to display user’s full name.oj: Library for both parsing and generating JSON with a ton of options.rack-mini-profiler: Middleware that provides performance profiling and diagnostics for Rack-based applications.pry: Debug APIs in real time.rubocop: Static code analyzer and code formatter enforcing Ruby code style conventions.bullet: Helps detecting and alerts N+1 database query issues in Rails applications.devise: A flexible and secure authentication solution for Ruby on Rails.cancancan: Authorization library that restricts user access based on user roles and permissions.annotate: Automatically adds schema information as comments to your models and specs.discard: Soft-delete implementation for ActiveRecord models.sidekiq: Simple and efficient background job processing for Ruby.friendlyId: Gem for creating human-readable URLs by using slugs for ActiveRecord models.paperclip: Gem for handling file attachments in Rails applications.In conclusion, embracing these practices will not only enhance the performance and scalability of your Rails applications but also contribute to a more enjoyable and productive development experience.Stay committed to continuous learning and improvement, and let these best practices guide you towards building high-quality Rails applications. Happy coding!Δdocument.getElementById( "ak_js_1" ).setAttribute( "value", ( new Date() ).getTime() );This site uses Akismet to reduce spam. Learn how your comment data is processed.



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Ruby on Rails Best Practices

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×