How to make dynamic template in ror... - ruby

I am new to ROR.I am working on spree gem extension. I want to make email template dynamic means the content of html.erb file should store in database table .On shooting mail, all data and dynamic data are managed..?? Is it possible in ror and how to achieve this.??

Yes you can do like this just replace dynamic variables in DB like this:
You have successfully placed Service Request No. {service_requests_id} for {service_requests_category} . Our representative will be in touch with you soon for the same. Thank you." This string is store in database.
and create a helper
def replace_dynamic_variables(str,variables=nil)
variables.each do |k ,v|
str = str.gsub('{' + k.to_s + '}',v || "")
end
return str.html_safe
end
and on mailer prepare variables like:
class yourMailer < ApplicationMailer
def send_service_email(args) # email sending method
#variables = {}
# Other code like subject, to, from etc.
#db_string = #string you get form DB
#variables[:service_requests_id] = #service_requests.id
#variables[:service_requests_category] = #service_requests.category.name
#mail to:
end
end
and in send_service_email.html.erb/ send_service_email.txt.erb whatever suite in your case just call
<%= replace_dynamic_variables(#db_string,#variables)%>
I have not tested but hope this will work for you

Related

In Rails, why are my controller params being modified by the class

I have a controller action somewhat similar to this:
def reports
puts params
#stats = Client.stats(params)
puts params
end
The initial params might look like this:
{ end: '2012-01-01 21:00:19' }
And in my Client model, I have this:
def self.stats(opts)
opts[:start] = (Time.now - 30.days).to_i
...do some calculations..
return stats
end
If I inspect the params object that was sent before and after the function runs, I can see it's been modified by the self.stats method.
In the example above, I'm not sending 'start' in the initial params, the method adds it for the calculations - as expected.
What I was not expecting was that the function would modify the original hash!
Can someone explain why this is happening?
--EDIT--
I forgot to say I tried to create a copy of the params and use that instead, same issue.
def reports
a = params
#stats = Client.stats(a)
puts params
end
The params are still updated?!
That's, because your function call gets a reference to the params not a copy. If you do something like opts[:start] = (Time.now - 30.days).to_i you are editing the params object.
a = params: now both variables point to the same place in the memory. You copied the pointer only.
Google for ruby object copy or ruby deep copy or search at stackoverflow for it. At a first try you could try params.clone.
Whenever you are updating any value of params, take a copy of params like this
a = params.clone
It will create a new element in memory
if you do like this it wont create a new element in memory it will point the same memory
a = params
Try this

How do I call a function in Ruby?

I'm trying to call but I keep getting an error. This is my code:
require 'rubygems'
require 'net/http'
require 'uri'
require 'json'
class AlchemyAPI
#Setup the endpoints
##ENDPOINTS = {}
##ENDPOINTS['taxonomy'] = {}
##ENDPOINTS['taxonomy']['url'] = '/url/URLGetRankedTaxonomy'
##ENDPOINTS['taxonomy']['text'] = '/text/TextGetRankedTaxonomy'
##ENDPOINTS['taxonomy']['html'] = '/html/HTMLGetRankedTaxonomy'
##BASE_URL = 'http://access.alchemyapi.com/calls'
def initialize()
begin
key = File.read('C:\Users\KVadher\Desktop\api_key.txt')
key.strip!
if key.empty?
#The key file should't be blank
puts 'The api_key.txt file appears to be blank, please copy/paste your API key in the file: api_key.txt'
puts 'If you do not have an API Key from AlchemyAPI please register for one at: http://www.alchemyapi.com/api/register.html'
Process.exit(1)
end
if key.length != 40
#Keys should be exactly 40 characters long
puts 'It appears that the key in api_key.txt is invalid. Please make sure the file only includes the API key, and it is the correct one.'
Process.exit(1)
end
#apiKey = key
rescue => err
#The file doesn't exist, so show the message and create the file.
puts 'API Key not found! Please copy/paste your API key into the file: api_key.txt'
puts 'If you do not have an API Key from AlchemyAPI please register for one at: http://www.alchemyapi.com/api/register.html'
#create a blank file to hold the key
File.open("api_key.txt", "w") {}
Process.exit(1)
end
end
# Categorizes the text for a URL, text or HTML.
# For an overview, please refer to: http://www.alchemyapi.com/products/features/text-categorization/
# For the docs, please refer to: http://www.alchemyapi.com/api/taxonomy/
#
# INPUT:
# flavor -> which version of the call, i.e. url, text or html.
# data -> the data to analyze, either the the url, text or html code.
# options -> various parameters that can be used to adjust how the API works, see below for more info on the available options.
#
# Available Options:
# showSourceText -> 0: disabled (default), 1: enabled.
#
# OUTPUT:
# The response, already converted from JSON to a Ruby object.
#
def taxonomy(flavor, data, options = {})
unless ##ENDPOINTS['taxonomy'].key?(flavor)
return { 'status'=>'ERROR', 'statusInfo'=>'Taxonomy info for ' + flavor + ' not available' }
end
#Add the URL encoded data to the options and analyze
options[flavor] = data
return analyze(##ENDPOINTS['taxonomy'][flavor], options)
print
end
**taxonomy(text,"trees",1)**
end
In ** ** I have entered my call. Am I doing something incorrect. The error I receive is:
C:/Users/KVadher/Desktop/testrub:139:in `<class:AlchemyAPI>': undefined local variable or method `text' for AlchemyAPI:Class (NameError)
from C:/Users/KVadher/Desktop/testrub:6:in `<main>'
I feel as though I'm calling as normal and that there is something wrong with the api code itself? Although I may be wrong.
Yes, as jon snow says, the function (method) call must be outside of the class. The methods are defined along with the class.
Also, Options should be a Hash, not a number, as you call options[flavor] = data, which is going to cause you another problem.
I believe maybe you meant to put text in quotes, as that is one of your flavors.
Furthermore, because you declared a class, this is called an instance method, and you must make an instance of the class to use this:
my_instance = AlchemyAPI.new
my_taxonomy = my_instance.taxonomy("text", "trees")
That's enough to get it to work, it seems like you have a ways to go to get this all working though. Good luck!

Rails3 api to retrieve items based on its params using grape

i m working in rails 3
i have a doubt , i have a method to fetch the items based on its tag
like
resources "blogs" do
get '/tag', '/tag/:name' do
authenticate!
tag_name = params[:name].to_s || ""
# query to fetch from items based on its tag associated
end
end
The above one works, now i would like to change the url like
"apipath/blogs?tag=tag1"
instead of what i did before as "apipath/blogs/tag/tag1"
so i have modified the line
get '/tag', '/tag/:name' do
###
end
with
get '?tag', '?tag=:name' do
end
but this not working ...
Please suggest .
To me this can works :
resources "blogs" do
get '/tag' do
authenticate!
tag_name = params[:tag].to_s || ""
# query to fetch from items based on its tag associated
end
end
You don't need define in your route the params pass by ? this is not interpret by router.
You can add conditionals in the route with parenthesis:
get '/tag(/:name)' do
# params[:name] will contain the tag name
end

Writing to excel files in ruby using roo gem

I am parsing Excel and Excelx file using Roo gem. But I am not sure how to write in those files. set_value(row, column, text) method is not working.
Code
#oo = Excelx.new('tes.xlsx')
#oo.default_sheet = #oo.sheets.first
def return_column
keywords = ["website", "url"]
keywords.each do |keyword|
1.upto(#oo.last_column) do |n|
data = #oo.cell(1, n)
return n if data.downcase=~/#{keyword}/i
end
end
end
def return_rows
n = return_n
2.upto(#oo.last_row) do |row|
data = #oo.cell(row, n)
stack << data
end
end
def appender
#oo.set_value(1,11, "hey")
end
appender
The Error Message I'm getting is
/.rvm/gems/ruby-1.8.7-p352/gems/roo-1.10.1/lib/roo/generic_spreadsheet.rb:441:in `method_missing': private method `set_value' called for #<Excelx:0x101221f08> (NoMethodError)
from /Users/bhushan/.rvm/gems/ruby-1.8.7-p352/gems/roo-1.10.1/lib/roo/excelx.rb:168:in `method_missing'
from parser.rb:32:in `appender'
from parser.rb:35
No answers here actually answer the question of how to do this with Roo, so I'll add the solution that I just tested in our app.
Roo recently added functionality for editing cells: https://github.com/roo-rb/roo/blob/master/lib/roo/csv.rb#L42
You can use it like such:
sheet.set_value(1, 5, 'TEST', nil) # to set the 1st row, 5th column to the string 'TEST'
Notes:
The last argument nil is not used in the function but has no default so it's required.
This is only added in version 2.7.0.
Try 'set' method instead of 'set_value' method in Excelx or OpenOffice object. For more refer API http://rubydoc.info/gems/roo/1.10.1/frames and I think roo gem specializes in reading excel contents than writing. For instance using set method will not save back to the spreadsheet file. It saves on the buffer I think. Try some other gems for writing
You can set the value of a column by pushing a string into it.
sheet.row(0).push 'some value'
The code below writes to a spreadsheet
require 'spreadsheet'
class Util::Table < ActiveRecord::Migration
def self.create_import_template
# create an xls workbook template for data importing based on models in activerecord
#format = Spreadsheet::Format.new(:weight => :bold)
#template_folder = File.join(Dir.home, 'Dropbox', 'horizon', 'data', 'templates')
#template_file = File.join(#template_folder, "data_import_template_#{Time.now.round(3).to_s.chomp(' -0700').gsub(':','-').gsub(' ','_').chop.chop.chop}.xls")
#book = Spreadsheet::Workbook.new
ActiveRecord::Base.send(:subclasses).each {|model| add_worksheet_to_template(model)}
#book.write #template_file
end
def self.add_worksheet_to_template(model)
# create a tab for each model that you wish to import data into
write_sheet = #book.create_worksheet :name => model
write_sheet.row(0).set_format(0, #format)
model.columns.each_with_index do |c,i|
column = ""
column << "*" unless c.null # indicate required field
column << c.name
write_sheet.row(0).set_format(i+1, #format)
write_sheet.row(0).push column
end
end
end
you can use set method
sheet.set(row, col, value)

Sinatra with a persistent variable

My sinatra app has to parse a ~60MB XML-file. This file hardly ever changes: on a nightly cron job, It is overwritten with another one.
Are there tricks or ways to keep the parsed file in memory, as a variable, so that I can read from it on incoming requests, but not have to parse it over and over for each incoming request?
Some Pseudocode to illustrate my problem.
get '/projects/:id'
return #nokigiri_object.search("//projects/project[#id=#{params[:id]}]/name/text()")
end
post '/projects/update'
if params[:token] == "s3cr3t"
#nokogiri_object = reparse_the_xml_file
end
end
What I need to know, is how to create such a #nokogiri_object so that it persists when Sinatra runs. Is that possible at all? Or do I need some storage for that?
You could try:
configure do
##nokogiri_object = parse_xml
end
Then ##nokogiri_object will be available in your request methods. It's a class variable rather than an instance variable, but should do what you want.
The proposed solution gives a warning
warning: class variable access from toplevel
You can use a class method to access the class variable and the warning will disappear
require 'sinatra'
class Cache
##count = 0
def self.init()
##count = 0
end
def self.increment()
##count = ##count + 1
end
def self.count()
return ##count
end
end
configure do
Cache::init()
end
get '/' do
if Cache::count() == 0
Cache::increment()
"First time"
else
Cache::increment()
"Another time #{Cache::count()}"
end
end
Two options:
Save the parsed file to a new file and always read that one.
You can save in a file – serialize - a hash with two keys: 'last-modified' and 'data'.
The 'last-modified' value is a date and you check in every request if that day is today. If it is not today then a new file is downloaded, parsed and stored with today's date.
The 'data' value is the parsed file.
That way you parse just once time, sort of a cache.
Save the parsed file to a NoSQL database, for example redis.

Resources