Convert string into reseved word in ROR - ruby-on-rails-3

I have this drop-down(how_often). If a user select 2 weeks then i want to send an email using delayed jobs like this:
mymailer.delay(:run_at => how_often.from_now).send_email
here I get "2.weeks" in how_often which is a string and the above code doesn't work as we can do as:
mymailer.delay(:run_at => 2.weeks.from_now).send_email
How to convert how_often(string) into reserved words like: 2.weeks, 2.months etc?

you could probably do it with eval:
mymailer.delay(:run_at => eval(how_often).from_now).send_email

Related

.NET Core - EF - trying to match/replace strings with digits, causes System.InvalidOperationException

I have to match records in SQL around a zip code with a min/max range
the challenge is that the data qualities are bad, some zipcodes are not numbers only
so I try to match "good zip codes" either by discarding bad ones or even keeping only digits
I dont know how to use Regex.Replace(..., #"[^\d]", "") instead of Regex.Match(..., #"\d") to fit in the query bellow
I get an error with the code bellow at runtime
I tried
Regex.IsMatch
SqlFunctions.IsNumeric
they all cause errors at runtime, here is the code :
var data = context.Leads.AsQueryable();
data = data.Include(p => p.Company).Include(p => p.Contact);
data = data.Where(p => Regex.IsMatch(p.Company.ZipCode, #"\d"));
data = data.Where(p => Convert.ToInt32(p.Company.ZipCode) >= range.Min);
data = data.Where(p => Convert.ToInt32(p.Company.ZipCode) <= range.Max);
here is the error :
System.InvalidOperationException: The LINQ expression 'DbSet<Lead>
.Join(
outer: DbSet<Company>,
inner: l => EF.Property<Nullable<int>>(l, "CompanyId"),
outerKeySelector: c => EF.Property<Nullable<int>>(c, "Id"),
innerKeySelector: (o, i) => new TransparentIdentifier<Lead, Company>(
Outer = o,
Inner = i
))
.Where(l => !(Regex.IsMatch(
input: l.Inner.ZipCode,
pattern: "\d")))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
I am not sure how to solve this. I really don't see how AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync() could help here
what do I do wrong ?
thanks for your help
Wnen you use querable list, Ef Core 5 is always trying to translate query to SQl, so you have to use code that SQL server could understand. If you want to use C# function you will have to download data to Server using ToList() or ToArray() at first and after this you can use any c# functions using downloaded data.
You can try something like this:
var data = context.Leads
.Include(p => p.Company)
.Include(p => p.Contact)
.Where(p =>
p.Company.Zipcode.All(char.IsDigit)
&& (Convert.ToInt32(p.Company.ZipCode) >= range.Min) //or >=1
&& ( Convert.ToInt32(p.Company.ZipCode) <= range.Max) ) // or <=99999
.ToArray();
I tried everything imaginable
all sorts of linq/ef trickeries, I even tried to define a DBFunction that was never found
once I had a running stored procedure written dirrectly in SQL, I ended up with a list, not with an IQueryable, so I was back to #1
finaly, I just created a new field in my table :
ZipCodeNum
which holds a filtered , converted version of the zipcode string

Variable To Get User Input Asterisk

I am writing an IVR and would like to get the keypad number the user dialled and store in in a variable. Does anyone know if asterisk defines such a channel variable? I cannot seem to find in in any variable lists.
I actually not clearly about your question.
As you said : "to get the keypad number the user dialled and store in in a variable"
so it very simple
exten => _X.,1,Noop(User dialed number: ${EXTEN});
So the variable you need is: ${EXTEN}
There are 2 main practice in dooing ivr
exten => s,1,Background(ivr-file-without-extension);play
exten => s,2,WaitExten(); wait for input
exten => 1,1,Noop(1 pressed); do something if 1
exten => 1,2,Set(result=1);for example set variable
Or
exten => s,1,Read(result,ivr-file-without-extension,max_digits);
exten => s,n,Noop(result=${result});
In both variants you can set up ANY variable name, thats why you can't find "magic" variable.
But i highly recommend you first read any single asterisk book for beginners. It is very unlikly you can do working app with your current knowledge(based on question asked).

Search on multiple keywords in a single search text field (RAILS)

I'm fairly new and playing around with searching databases in Rails. I have a model and database that has a list of names under the 'name' attribute. I want to be able to enter search keywords into a single search field and this input can be one word or two words or more, depending on how specific a result the user wants.
Right now, I'm using something ugly as shown below, which will do a maximum of 3 search terms. Is there a way to make this dynamic for 'search_length' keywords? The find method is clearly repetitive, but I'm not sure how to automate it and haven't found any useful suggestions elsewhere online.
def self.search(search)
if search
search_length = search.split.length
find(:all, :conditions => ['name LIKE ? AND name LIKE ? AND name LIKE ?',
"%#{search.split[0]}%", "%#{search.split[1]}%",
"%#{search.split[search_length1]}%"])
else
find(:all)
end
end
Other than this, loving Rails so far.
Thanks Much,
Lev
The code from Łukasz Śliwa works great if you close the name variable with the other % sign.
The complete code from above working for me. Great post.
def self.search(search)
if search
search_length = search.split.length
find(:all, :conditions => [(['name LIKE ?'] * search_length).join(' AND ')] + search.split.map { |name| "%#{name}%" })
else
find(:all)
end
end
Use something like this:
find(:all, :conditions => [(['name LIKE ?'] * search_length).join(' AND ')] + search.split.map { |name| "%#{name}" })
I looks strange but, first generate search_length times string 'name LIKE ?':
['name LIKE ?'] * search_length
then you have array with some keys, so let's join all of them with ' AND ':
["name LIKE ? ", "name LIKE ? ", "name LIKE ? "].join(' AND ')
and finally merge with another array.
formatted_columns = format_column_names(Sub.column_names)
where(formatted_columns.map {|cn| "#{cn} like ?" }.join("or "), *(["%#{search}%"] * formatted_columns.size))
this takes care of all columns as well as the correct amount of fields

assigning random url to a resource in rails 3

I need to generate a random url to my Topic model(for example) as such:
http://localhost:3000/9ARb123
So how can I do this in rails?
Note: the random string must contain digits, small and capital letters.
Something like this perhaps
#config/routes.rb
match "/:random_id" => "topics#show", :constraints => {:random_id => /([a-zA-Z]|\d){3,6}/}
will match a random string of 3-6 random letters/numbers to the show method of your Topics controller. Make sure to declare other resources above this matcher, as something like "http://localhost:3000/pies" will route to Topics#show instead of Pies#index.
To generate a random url for your Topic you can go something like this:
#app/models/topic.rb
before_create :generate_random_id
def generate_random_id
#generates a random hex string of length 6
random_id = SecureRandom.hex(3)
end
Patricks answer should work - but it only covers routing incoming requests.
If you're still using the standard routes (eg topic_path) to create your links, it will still use the normal routes.
If you run rake routes, you should see the name of the route you created with with the random_id. (You may need to name it using :as => 'random_route')
If you call that instead of the standard topic_path you should get the route you are after

Replace space with dash before save using Rails 3

I am trying to save a name to the database and a single word (firstname) works fine but when the user enter both firstname and lastname I want Rails to save it to the database as firstname-lastname instead of firstname lastname (space between).
I know I perhaps should use a before create filter but I am not sure how this need to look like. I want the validation to work to, i.e. no two people should be able to use the same name.
I am using Rails 3.
You can use ActiveSupport's inflector method parameterize on the string.
name = 'john smith' # => john smith
name.parameterize # => john-smith
Further, parameterize takes an option to use for the word-break, so you can replace the dash with an underscore like this:
name.parameterize("_") # => john_smith
An advantage of using parameterize is that it normalizes the characters to the latin, so...
name = "jöhanne såltveç"
name.parameterize # => johanne-saltvec
EDIT: As of Rails 5.0.0.1 the separator needs to be passed as an option. Therefore: name.parameterize(separator: '_')
Why don't you just have first_name and last_name columns in the db, and create your own validation rule to make sure the combination is unique (http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods). You should also create a unique index over those two columns in your db.
Another option would be to us regexp and replace all existing spaces with. You'd put something along the lines of:
self.firstname.gsub(/\s+/, '-')
in your model.
Note: I'm not sure if ruby accepts \s as "any whitespace character" And I think the * should make sure that if someone enters a name with two neighbour spaces(or more) it won't convert each space into a separate dash, but only into one.
Other answer is correct,
But, if you want to preserve case while parameterizing
name = "Donald Duck"
name.parameterize(preserve_case: true) # => Donald-Duck