Rails accepts a Range as value in a #where hash condition:
sizes = "160-180" # this comes from your DB I presume
min, max = sizes.split('-').collect(&:to_i)
Shirt.where(size: min..max)
If you want to check if the parameter provided is within range, it's just as simple:
def valid_size?
sizes = "160-180" # again from your shirt in DB
min, max = sizes.split('-').collect(&:to_i) # when you get tired of this line, it means it's time to refactor it
# collapse the following into one line
params[:size] && # check for presence
params[:size].between?(min, max) && # check if in range
params[:size] # I guess you want to return the size if valid, rather than only a boolean
end
# Alternative checks, that don't need the presence check:
# - (min..max).member?(params[:size])
# - (min..max).include?(params[:size])
# I choose what I find more explicit and readable
Finally, I agree you should migrate the DB to have min and max size stored as two separate integers. So as usual, write a test for your function, then code the simplest solution to get the tests green. At that point, by all means, go ahead and refactor your DB :)
# migration
def up
add_column :shirts, :min_size, :integer
add_column :shirts, :max_size, :integer
Shirt.find_each do |shirt|
min, max = shirt.size.split('-').collect(&:to_i) # for the last time :)
shirt.min_size = min
shirt.max_size = max
shirt.save!
end
remove_column :shirts, :size
end
def down
add_column :shirts, :size, :string
Shirt.find_each do |shirt|
size = "#{shirt.min_size}-#{shirt.max_size}"
shirt.size = size
shirt.save!
end
remove_column :shirts, :min_size, :integer
remove_column :shirts, :max_size, :integer
end