How to use Range data type in creating Rails model?

Using Rails version 3. I want to create a model in which I have a field called "Page Visits." I want it to hold the range as a value, for example: (50 .. 100), (1000 .. 5000), etc. How to do it?? Even if this type of data is not currently on the rails, I would like to know other ways to achieve this?

+3
source share
3 answers

I assume that you really want to keep the range in your model, not the value within the range. (If you want to do the latter, validation will be your answer).

So the range. In the model. You have two options, each of which is pretty decent.

Option 1: Create a column ( range_column) of type text. Pass a Ruby range object to a column, for example @my_model_object.range_column = (50..100). Tell Rails to serialize your range as follows:

class MyModel < ActiveRecord::Base
  serialize :range_column
end

Now Rails will automatically convert your range to YAML for storing the database and convert it back to a range object when it retrieves the record again. Not much easier than that!

Option 2: Create two columns ( range_startand range_end) the type 'integer'. Set up something in your model as follows:

class MyModel < ActiveRecord::Base
  def range=(rstart, rend)
    self.range_start = rstart
    self.range_end   = rend
  end

  def range
    (range_start..range_end) # or as an array, or however you want to return it
  end
end

The first option is simpler (and, in my opinion, better), and the second gives you a little flexibility out of the box if you don't want to use a Ruby range object (though, why would you?).

+7

page_visits, , ,

def page_visit_range
  #case when statement for self.page_visits or some smarter maths to return range
end
+1

Rails has a range data type if your database supports it.

Here is a postgresql example: Rails range types with PostgreSQL

# db/migrate/20130923065404_create_events.rb
create_table :events do |t|
  t.daterange 'duration'
end

# app/models/event.rb
class Event < ApplicationRecord
end

# Usage
Event.create(duration: Date.new(2014, 2, 11)..Date.new(2014, 2, 12))

event = Event.first
event.duration # => Tue, 11 Feb 2014...Thu, 13 Feb 2014

## All Events on a given date
Event.where("duration @> ?::date", Date.new(2014, 2, 12))

## Working with range bounds
event = Event.
  select("lower(duration) AS starts_at").
  select("upper(duration) AS ends_at").first

event.starts_at # => Tue, 11 Feb 2014
event.ends_at # => Thu, 13 Feb 2014
0
source

Source: https://habr.com/ru/post/1769848/


All Articles