How to use a Range data-type in Rails model creation?
Am using Rails version 3. I want to create a model , in which i have a field called "Page-visits" I want it to hold range as value, eg: (50 .. 100) , (1000 .. 5000) etc. How to achieve this ?? 开发者_StackOverflowEven if there is no such data-type at present in rails, I would like to know other ways of how to achieve this ?
I'm assuming that you actually want to store a range in your model, and not a value within a range. (If you wanted to do the latter, validations would be your answer).
So, range. In a model. You've got two options, each of which are pretty decent.
Option 1: Create a column (range_column
) with type 'text'. Pass a Ruby range object to the column, like @my_model_object.range_column = (50..100)
. Tell Rails to serialize your range like this:
class MyModel < ActiveRecord::Base
serialize :range_column
end
Now, Rails will automatically convert your range to YAML for database storage, and convert it back to the range object when it retrieves the record again. Doesn't get much easier than that!
Option 2: Create two columns (range_start
and range_end
) with type 'integer'. Set up something in your model like this:
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 easier (and, in my opinion, better), while the second gives you a tad bit more flexibility out of the box in case you don't want to use a Ruby range object (though, why wouldn't you?).
Rails has a range datatype 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
I would suggest creating model with attribute page_visits which holds exact amount of visits and define method in action, smth like
def page_visit_range
#case when statement for self.page_visits or some smarter maths to return range
end
精彩评论