I have the following in my url. I need to extract both 4 and 2 separately for the purpose of searching. These two integer, one is category id and other is sub category id
params[:id].scan(/\d+$/).first
using the above scan i can get 4 but how can i get more than one integers
my-url-for-test-4-2
I have created a helper method
def string_to_int(param,key)
param.scan(/\d+/).map(&:to_i).key
end
And i tried it from my controller like this
id = string_to_int(params[:id],'first')
But getting error as
undefined method `key' for [4, 2]:Array
Why it is not acception.
Answer lies in your question
params[:id].scan(/\d/) will result in array.
params[:id].scan(/\d+/).map(&:to_i)
If you are passing first or last as key :
def string_to_int(param,key)
param[:id].scan(/\d+/).map(&:to_i).send(key)
end
You can match against the last two numerical parts (separated by hyphens) in your :id parameter:
string = params[:id].to_s
ids = string.scan(/-(\d+)-(\d+)$/)[0] # .try(:map, &:to_i)
Update:
Here's a not-too-edge case that would be handled well:
a = "random1-2string-3-4-5"
a.scan(/-(\d+)-(\d+)$/) # => [["4", "5"]]
a.scan(/-(\d+)-(\d+)$/)[0] # => ["4", "5"]
a.scan(/-(\d+)-(\d+)$/)[0].try(:map, &:to_i) # => [4, 5]
Related
I'm not sure how is this implemented, when you do something like:
Model.where(["subjects = ?", 1])
Rails allows you to omit the braces:
Model.where("subjects = ?", 1)
I know this is possible with hashes, but how is it possible so you can pass ANY number of arguments (you can have 100 question marks if you want) and for Rails to still interpret this as an array?
In Ruby a method can accept splat arguments.
def foo(*a)
a
end
foo('bar', 'baz')
# => ["bar", "baz"]
The splat gathers up any remaining arguments. You can even use it with regular arguments:
def foo(a, *b)
b
end
foo('bar', 'baz')
# => ["baz"]
You can even do something like:
def foo(*a)
a.length == 1 && a.first.is_a?(Array) ? a.first : a
end
Now calling foo('bar', 'baz') and foo(['bar', 'baz']) have the same return value.
However if what you want is a WHERE condition where the value can be one of many possible values you would write it like so:
Model.where(foo: [1, 2, 3, 5])
Which would create a WHERE models.foo IN (1,2,3,5) clause.
From the Docs
Model.where(array)
If an array is passed, then the first element of the array is treated as a template, and the remaining elements are inserted into the template to generate the condition. Active Record takes care of building the query to avoid injection attacks, and will convert from the ruby type to the database type where needed. Elements are inserted into the string in the order in which they appear.
User.where(["name = ? and email = ?", "Joe", "joe#example.com"])
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe#example.com';
I need to Separate multiple Array entries with a newline.
the names in the aray value. Again I want to split the array like seperate names.
Eg. names="alice\nbob"
and I want names=alice&names=bob. How can I get that??
Try this:
names="alice\nbob"
names = names.split("\n").map{|item| "names=#{item}"}.join("&")
#=> "names=alice&names=bob"
If intention is to have it in form of query parameters, I will suggest using Addressable::URI:
require "addressable/uri"
def return_query(str)
uri = Addressable::URI.new
uri.query_values = {:names => str.split("\n") }
uri.query
end
return_query("alice\nbob") #=> "names=alice&names=bob"
return_query("alice in wonderland\nbob") #=> "names=alice%20in%20wonderland&names=bob"
return_query("alice&wonderland\nbob") #=> "names=alice%26wonderland&names=bob"
I have an application that dynamically creates a drop-down menu based on certain values in the database. Often the drop-down values are just in the order they come up but I would like to put them in a certain order.
An example of my value system:
Newbie = 0
Amateur = 1
Skilled = 2
Pro = 3
GrandMaster = 4
How would I take the data above and use it to sort an array full of those values (Newbie etc). I've thought about creating a hash of the values but even then I still am not sure how to apply that to the sort method.
Any help would be appreciated.
You can sort this array just by using the usual sorting the sorting won't be done by name it will be done by value. and if these are not integer objects and are some user defined class then sorting based on a particular attribute can be achieved very efficiently by
lst.sort_by &:first
where first is the attribute of the object.
Sort has by value:
hash = {:Newbie=>0, :Amateur=>1, :Skilled=>2, :Pro=>3}
> hash.sort { hash{a} <=> hash{b} }
=> [[:Newbie, 0], [:Amateur, 1], [:Skilled, 2], [:Pro, 3]]
Or use Ruby Hash#sort_by method:
hash.sort_by { |k,v| v }
Suppose you have a Level model that has a sort_id identifying the displayed order and a name holding the displayed name. I recommend using default_scope to set the default order for that model because it is likely that you always want to sort Level records this way:
class Level < ActiveRecord::Base
#### attributes
# id (integer)
# name (string)
# sort_id (integer)
default_scope order('sort_id ASC')
# rest of model...
end
Then, the only thing you have to do in your view to display a picklist is
<%= f.select("level", Level.pluck(:name)) %>
An alternate to #padde. I prefer to avoid default scopes.
class Level < ActiveRecord::Base
#### attributes
# id (integer)
# name (string)
# value (integer)
end
In the view
<%= f.select("level", Level.order(:value).map{|l| [l.name, l.value] } %>
Due to my poorly explained question the others trying to answer my question didn't really get a chance but using their help I did manage to figure out my problem.
ex_array = ["GrandMaster", "Newbie", "Pro", "Skilled", "Amateur"]
value_sys = {:Newbie=>0, :Amateur=>1, :Skilled=>2, :Pro=>3, :GrandMaster=>4}
ex_array.sort { |a,b| value_sys[a.to_sym] <=> value_sys[b.to_sym]
=> ["Newbie", "Amateur", "Skilled","Pro", "GrandMaster"]
Thanks for the help guys. Much appreciated.
Parse your value system for further use:
values = <<EOF
Newbie = 0
Amateur = 1
Skilled = 2
Pro = 3
GrandMaster = 4
EOF
value_map = Hash[values.split("\n").map{|v| v.split(/\s*=\s*/)}.map{|v| [v[0], v[1].to_i]}]
#=> {"Newbie"=>0, "Amateur"=>1, "Skilled"=>2, "Pro"=>3, "GrandMaster"=>4}
Assign the array values a weight according to value_map to transform the array into a new one, sort according to the weight, and then transform the new array back.
# here I created a sample array
array = value_map.keys.shuffle
#=> ["Newbie", "Pro", "Skilled", "Amateur", "GrandMaster"]
# transform and sort
sorted = array.map{|v| [v, value_map[v] || 0xFFFF]}.sort_by{|v| v[1]}.map{|v| v[0]}
#=> ["Newbie", "Amateur", "Skilled", "Pro", "GrandMaster"]
Or you can bypass the transform step and just use the sort_by method:
sorted = array.sort_by{|v| value_map[v] || 0xFFFF}
How can I do something like this in range?
User.find(14000..14500)
I need to choose a certain range of Users starting and finishing on specifics ids.
You can use the where method:
User.where(id: 14000..14500)
Explanation
The where method here receives a hash argument in its shortened form, where the value for the id key is a Range.
You can do it like this too:
User.find_by_id(14000..14500)
Try this also
User.find((start..end).to_a)
Ex -
User.find((14000..14500).to_a)
You can use range definition for scoped:
User.find(1) # returns the object for ID = 1
User.find([1])
User.find(1, 2, 9) # returns an array for objects with IDs in (1, 2, 9)
User.find([1, 2, 9])
User.scoped(:conditions => { :id => 1..9})
I am trying to split a string, and output the different parts, whats the best practice for rails 3 ?
String: "book_page_title"
Seperator: "_"
I want to have book, page and title as seperate variables, so that
I can perform actions on them..
Any help is appreciated.
Also, I am having trouble finding good reference sites, with examples like PHP have, and suggestions ?
To split:
book,page,title = string.split('_')
And to recombine:
string = [book,page,title].join('_')
use
split('_')
method it gives array.
Try ruby+string+doc in google, you will get http://ruby-doc.org/core/classes/String.html as the first result, and you can see a number of string functions in this link. You can see split there.
splitted_array = "book_page_title".split("_")
=> ["book", "page", "title"]
splitted_array.each do |string|
#..do manipulations here
end
"book_page_title".split("_") will return you array of strings. So you can access every element via [].
splitted = "book_page_title".split("_") # ["book", "page", "title"]
puts splitted[0] # gives "book"
puts splitted[1] # gives "page"
puts splitted[2] # gives "title"
a = "book_page_title".split("_")
a.each do |i|
instance_variable_set("##{i}", "value")
end
#book #=> *value*
#page #=> *value*
#title #=> *value*