module

ActiveRecord::Enum

rails latest stable

Declare an enum attribute where the values map to integers in the database, but can be queried by name. Example:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end

# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status  # => "active"

# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status    # => "archived"

# conversation.status = 1
conversation.status = "archived"

conversation.status = nil
conversation.status.nil? # => true
conversation.status      # => nil

Scopes based on the allowed values of the enum field will be provided as well. With the above example:

Conversation.active
Conversation.not_active
Conversation.archived
Conversation.not_archived

Of course, you can also query them directly if the scopes don’t fit your needs:

Conversation.where(status: [:active, :archived])
Conversation.where.not(status: :active)

Defining scopes can be disabled by setting :scopes to false.

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], scopes: false
end

You can set the default enum value by setting :default, like:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], default: :active
end

conversation = Conversation.new
conversation.status # => "active"

It’s possible to explicitly map the relation between attribute and database integer with a hash:

class Conversation < ActiveRecord::Base
  enum :status, active: 0, archived: 1
end

Finally it’s also possible to use a string column to persist the enumerated value. Note that this will likely lead to slower database queries:

class Conversation < ActiveRecord::Base
  enum :status, active: "active", archived: "archived"
end

Note that when an array is used, the implicit mapping from the values to database integers is derived from the order the values appear in the array. In the example, :active is mapped to 0 as it’s the first element, and :archived is mapped to 1. In general, the i-th element is mapped to i-1 in the database.

Therefore, once a value is added to the enum array, its position in the array must be maintained, and new values should only be added to the end of the array. To remove unused values, the explicit hash syntax should be used.

In rare circumstances you might need to access the mapping directly. The mappings are exposed through a class method with the pluralized attribute name, which return the mapping in a ActiveSupport::HashWithIndifferentAccess :

Conversation.statuses[:active]    # => 0
Conversation.statuses["archived"] # => 1

Use that class method when you need to know the ordinal value of an enum. For example, you can use that when manually building SQL strings:

Conversation.where("status <> ?", Conversation.statuses[:archived])

You can use the :prefix or :suffix options when you need to define multiple enums with same values. If the passed value is true, the methods are prefixed/suffixed with the name of the enum. It is also possible to supply a custom value:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], suffix: true
  enum :comments_status, [ :active, :inactive ], prefix: :comments
end

With the above example, the bang and predicate methods along with the associated scopes are now prefixed and/or suffixed accordingly:

conversation.active_status!
conversation.archived_status? # => false

conversation.comments_inactive!
conversation.comments_active? # => false

If you want to disable the auto-generated methods on the model, you can do so by setting the :instance_methods option to false:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], instance_methods: false
end

If you want the enum value to be validated before saving, use the option :validate:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], validate: true
end

conversation = Conversation.new

conversation.status = :unknown
conversation.valid? # => false

conversation.status = nil
conversation.valid? # => false

conversation.status = :active
conversation.valid? # => true

It is also possible to pass additional validation options:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ], validate: { allow_nil: true }
end

conversation = Conversation.new

conversation.status = :unknown
conversation.valid? # => false

conversation.status = nil
conversation.valid? # => true

conversation.status = :active
conversation.valid? # => true

Otherwise ArgumentError will raise:

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end

conversation = Conversation.new

conversation.status = :unknown # 'unknown' is not a valid status (ArgumentError)

Constants

ENUM_CONFLICT_MESSAGE = \\\n"You tried to define an enum named \\"%{enum}\\" on the model \\"%{klass}\\", but " \\\n"this will generate a %{type} method \\"%{method}\\", which is already defined " \\\n"by %{source}."

Files

  • activerecord/lib/active_record/enum.rb

5Notes

Text values for enum

mustai · Feb 14, 20161 thank

There is way to have text values for enum. It is useful to have localized select options and latin values in database.

  1. User model: enum kind: { 'текст'=>'text', 'изображение'=>'picture', 'звук'=>'audio', 'видео'=>'video' }
  2. Edit view: <%= select_tag 'user[kind]', options_for_select(User.kinds, @user.kind) %>

Integrate enum with PostgreSQL Enumerated Types

tinogomes · Aug 21, 20161 thank

Extract from:

http://www.sitepoint.com/enumerated-types-with-activerecord-and-postgresql/

There are 2 things that we need to do before we can use ActiveRecord::Enum with PostgreSQL Enumerated Types: database migration and enum declaration.

First, let’s create the database migration:

$ bundle exec rails generate migration AddGenderToUsers gender:gender

Next, edit the generated migration to add the type:

db/migrate/20150619131527_add_gender_to_users.rb

class AddGenderToUsers < ActiveRecord::Migration def up execute <<-SQL CREATE TYPE gender AS ENUM ('male', 'female', 'not_sure', 'prefer_not_to_disclose'); SQL

 add_column :users, :gender, :gender, index: true

end

def down remove_column :users, :gender

 execute <<-SQL
   DROP TYPE gender;
 SQL

end end

Once you’re finished with that, run the migration:

$ bundle exec rake db:migrate

Now, we have completed the database migration. The next step is to declare an enum in the User model. Earlier, we used both the Array and Hash forms to declare an enum. For the integration to work, we need to declare an enum using the Hash form:

app/models/user.rb

class User < ActiveRecord::Base enum gender: { male: 'male', female: 'female', not_sure: 'not_sure', prefer_not_to_disclose: 'prefer_not_to_disclose' } end

Finally, we can store ActiveRecord::Enum values using PostgreSQL Enumerated Types. As a bonus, all helper methods provided by ActiveRecord::Enum still work as expected.

Previewing Emails in Rails Applications With the Mail_View Gem

rubyonrailsdevelopment · Sep 1, 2016

Sending an email from an application through a development or staging environment can be cumbersome especially when you want to preview the mail before you hit the send button. With the gem ‘mail_view, you can easily preview emails right from your development environment. Previewing mail is important to ensure that you are sending the right email and to the right person.

Never send a mail in dark anymore with the ‘mail_view gem! Check out more below on how it can be implemented in your application during the development stage.

Rails Email Preview helps us to quickly view the email in web browser in development mode.

  1. Add “gem ‘rails_email_preview’, ‘~> 0.2.29’ “ to gem file and bundle install.
  2. Run “rails g rails_email_preview:install” this creates initializer in config folder and add routes.
  3. Run “rails g rails_email_preview:update_previews” this crates mailer_previews folder in app directory. Generator will add a stub to each of your emails, then u populate the stub with mock data.

Ex:

class UserMailerPreview
def invitation
UserMailer.invitation mock_user(‘Alice’), mock_user(‘Bob’)
end

def welcome
UserMailer.welcome mock_user
end

private
def mock_user(name = ‘Bill Gates’)
fake_id User.new(name: name, email: “user#{rand 100}@test.com”)
end

def fake_id(obj)
obj.define_singleton_method(:id) { 123 + rand(100) }
obj
end
end
  1. Parameters in search query will be available as an instance variable to preview class.

Ex: if we have a URL like “/emails/user_mailer_preview-welcome?user_id=1” @user_id is defined in welcome method of UserMailerPreview it helps us to send mail to specific user.

class UserMailerPreview
def welcome
user = @user_id ? User.find(@user_id) : mock_user
UserMailer.welcome(user)
end
end
  1. To access REP url’s like this

    rails_email_preview.rep_root_url rails_email_preview.rep_emails_url rails_email_preview.rep_email_url(‘user_mailer-welcome’)

  2. We can send emails via REP, this will use environment mailer settings. Uncomment this line in the initializer to disable sending mail in test environment.

    config.enable_send_email = false

References :

  1. https://github.com/glebm/rails_email_preview
  2. https://richonrails.com/articles/action-mailer-previews-in-ruby-on-rails-4-1 Read More From Here>>> http://goo.gl/KQBk5S

How To Generate a Swagger Docs For Rails API

rubyonrailsdevelopment · Oct 3, 2016

Making API for a Rails application is simple for a Ruby on Rails developer. In any case, how different clients/customers will know whether the API is working fine or not without a customer side application. Is there any answer for this which I can report for API inside the Rails application, The answer is yes we have numerous instruments and methodologies however I would favor swagger UI.

In this article I am going to disclose how to make Rails API documentation using swagger UI.

Prerequisites:- I am going to use one sample posts application which serves API calls.

Gem:- To Integrate swagger UI for Rails API I am using a gem called swagger-docs. Add this gem to your Gemfile in your application and do bundle install.

Swagger initializer file:- After bundling the gem create an initializer in config/initializers(e.g. swagger.rb) and specify the following options:

#File config/initializers/swagger.rb

Swagger::Docs::Config.register_apis({

"1.0" => {

the extension used for the API

:api_extension_type => :json,

the output location where your .json files are written to

:api_file_path => "public/apidocs",

the URL base path to your API

:base_path => "http://localhost:3000",

if you want to delete all .json files at each generation

:clean_directory => true,

add custom attributes to api-docs

:attributes => {

:info => {

"title" => "Your application title",

"description" => "Rails API documention with Swagger UI.",

"termsOfServiceUrl" => "",

"contact" => ""

}

}

}

})

Refer below url for the list of configarations https://github.com/richhollis/swagger-docs#configuration-options

swagger_controller and swagger_API are helpers to provide swagger UI documentation.

module Api

module V1

class PostsController < ApplicationController

respond_to :json

swagger_controller :posts, 'Post Controller'

swagger_api :create do

summary 'Creating posts'

notes 'Should be used for creating posts'

param :form, 'post[name]', :string, :required, 'name'

param :form, 'post[publish]', :boolean, :required, 'publish'

end

swagger_api :index do

summary 'Get all the posts'

notes 'Should be used for fetching all posts'

param :header, :Authoraization, :string, :required, 'Authoraization'

response :unauthorized

response :ok, "Success"

end

swagger_api :show do

summary 'Get all the posts'

notes 'Should be used for fetching a post'

param :path, :id, :string, :id

response :unauthorized

response :ok, "Success"

end

swagger_api :destroy do

summary 'Destroy the post'

notes 'Should be used for destroying a post'

param :path, :id, :string, :id

response :unauthorized

response :ok, "Success"

end

end

end

end

Read More From Here http://goo.gl/dMVHon

How to generate & add sitemap to your Rails Application

rubyonrailsdevelopment · Oct 17, 2016

Generate Sitemap: Required Gem: Sitemap generator:- https://github.com/kjvarga/sitemap_generator SitemapGenerator is the easiest way to generate Sitemaps in Ruby. Rails integration provides access to the Rails route helpers within our sitemap config file and automatically makes the rake tasks available to us. Or if we prefer to use another framework, we can! We can use the rake tasks provided or run our sitemap configs as plain ruby scripts.

Sitemaps XML format:

The Sitemap protocol format consists of XML tags. All data values in a Sitemap must be entity-escaped. The file itself must be UTF-8 encoded.

The Sitemap must: Begin with an opening tag and end with a closing tag. Specify the namespace (protocol standard) within the tag. Include a entry for each URL, as a parent XML tag. Include a child entry for each parent tag.

All other tags are optional. Also, all URLs in a Sitemap must be from a single host, such as www.xyz.com or estore.xyz.com. For more details: http://www.sitemaps.org/protocol.html

How to add a sitemap to a Rails app:

1, View for your sitemap:

app/views/mysitemap/index.xml.erb

2, At your Controller: Let it be our object in view is @articles variable. It needs to get that from a mysitemap controller:

app/controllers /mysitemap_controller.rb

MysitemapController < ApplicationController layout nil def index headers['Content-Type'] = 'application/xml' respond_to do |format| format.xml {@articles = Article.all} end end end 3, Add a route:

config/routes.rb

get 'sitemap.xml', :to => 'sitemap#index', :defaults => {:format => 'xml'}

How to convert XML file to HTML: Read From Here http://goo.gl/Vp3chb