I have passed dynamic content to the body of the email. But looking at the API docs the subject params only accepts a string and not an array.
Is there a way to pass a dynamic subject? I would like to pass the name of the recipient in the subject
I have the following right now:
m = Mandrill::API.new ENV['MANDRILL_APIKEY']
message = {
:subject=> template.subject,
:from_name=> template.name,
:from_email=> template.from + "#" + email_domain,
:to=>mails,
:global_merge_vars=> [
{ :name => 'IMAGE', :content => image_tag},
],
:html=>email_template,
:preserve_recipients => false,
:merge_vars => variables,
}
It seems that Mandrill reads merge variables in the subject as well. So it is as simple as adding *|SOME_VAR|* in your subject text and then passing it as a parameter in the merge_vars.
More details here.
Related
I've got a hash that I define in my plot controller, under the edit action
#custom_params = { :custom_plot_type => "Line", :x_axis_title => "", :x_low => "", :x_high => "", :y_axis_title => "", :y_low => "", :y_high => "" }
When I visit the edit page, I have a form_with #plot as the model containing the following select box:
= fields_for :custom_params do |c|
= c.label(':custom_plot_type', "Plot Type")
= c.select(:custom_plot_type, options_for_select(['Line', 'Scatter', 'Heat Map', 'Column'], #custom_params[:custom_plot_type]))
Rails gives me the following error
undefined method `custom_plot_type' for #< Hash:0x00007ffff8c4b030>
I have followed the answer on this question and I'm pretty sure my definition of the hash is correct. But no matter which way I format it (for example, using "custom_plot_type" => "Line" and #custom_params["custom_plot_type"] instead) I get the same error in the view.
I can also output the element I want in the console within the controller, using
puts #custom_params
puts #custom_params[:custom_plot_type]
This outputs the correct value, but as soon as I try to access it in the view it crashes
Edit: Adding more information about the form to clarify in response to a comment. My form is structured as follows:
= form_with(model: #plot, local: true, method: "patch") do |f|
= label_tag('plot[name]', "New plot name:")
= text_field_tag('plot[name]', #plot.name)
%br
= label_tag('plot[description]', "Description:")
= text_field_tag('plot[description]', #plot.description)
%br
%br
= fields_for :custom_params do |c|
= c.label(':custom_plot_type', "Plot Type")
= c.select(:custom_plot_type, options_for_select(['Line', 'Scatter', 'Heat Map', 'Column'], #custom_params[:custom_plot_type]))
The thinking behind this was to have the a form that has fields that are associated with the Plot model, and also to have a subform for "custom params" that are not associated with the model itself but will be saved to a file. So the form does have a model instance associated with it, but the select tag in question does not.
I edited the form to use a select_tag instead of a c.select element, as follows:
= fields_for :custom_params do |c|
= label_tag('custom_params[:custom_plot_type]', "Plot Type")
= select_tag('custom_params[:custom_plot_type]', options_for_select(['Line', 'Scatter', 'Heat Map', 'Column'], #custom_params[:custom_plot_type]))
I still use the value of c for other form elements later on, but using _tag elements instead of elements related to the form builder allow me to use the arbitrary hash within the select tag - thanks #tgmerritt for the suggestion
I'm playing around with with external APIs from League of Legends. So far, I've been able to get a response from the API, which returns a JSON object.
#test_summoner_name = ERB::Util.url_encode('Jimbo')
#url = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/#{#test_summoner_name}?api_key=#{RIOT_API_KEY}"
response = HTTParty.get(#url)
#summoner = JSON.parse(response.body)
#summoner_name = #summoner[:name]
The JSON object looks like this:
{"jimbo"=>{"id"=>12345678, "name"=>"Jimbo", "profileIconId"=>1234, "revisionDate"=>123456789012, "summonerLevel"=>10}}
So, I'm able to output the JSON object with my #summoner variable in my view. But when I try to output my #summoner_name variable, I just get a blank string.
For reference, this is my view currently:
Summoner Object: <%= #summoner %><br>
Summoner Name: <%= #summoner_name %>
Any help would be greatly appreciated. I've been stumbling through this process all day now.
Problem
You don't have the hash you think you do. Once you've parsed your JSON, your #summoner instance variable actually contains everything else wrapped under a hash key named jimbo. For example, when using the awesome_print gem to pretty-print your hash, you will see:
require 'awesome_print'
ap #summoner, indent: 2, index: false
{
"jimbo" => {
"id" => 12345678,
"name" => "Jimbo",
"profileIconId" => 1234,
"revisionDate" => 123456789012,
"summonerLevel" => 10
}
}
Solution
To get at the name key, you have to go deeper into the hash. For example, you can use Hash#dig like so:
#summoner_name = #summoner.dig 'jimbo', 'name'
#=> "Jimbo"
If you're using an older Ruby without the Hash#dig method, then you can still get at the value by specifying a sub-key as follows:
#summoner_name = #summoner['jimbo']['name']
#=> "Jimbo"
It migth help if you look your json like this:
{"jimbo"=>{
"id"=>12345678,
"name"=>"Jimbo",
"profileIconId"=>1234,
"revisionDate"=>123456789012,
"summonerLevel"=>10}
}
Then you could just do
#summoner_jimbo_name = #summoner['jimbo']['name']
to get the value:
Jimbo
First of all, I am very new to ruby and I am trying to maintain an application already running in production.
I have been so far able to "interpret" the code well, but there is one thing I am stuck at.
I have a haml.html file where I am trying to display links from DB.
Imagine a DB structure like below
link_name - Home
URL - /home.html
class - clear
id - homeId
I display a link on the page as below
< a href="/home.html" class="clear" id="home" > Home </a>
To do this I use 'link_to' where I am adding code as follows
-link_to model.link_name , model.url, {:class => model.class ...... }
Now I have a new requirement where we have a free text in DB, something like -
data-help="home-help" data-redirect="home-redirect" which needs to come into the options.
So code in haml needs to directly display content versus assign it to a variable to display.
In other words I am able to do
attr= '"data-help="home-help" data-redirect="home-redirect"' inside the <a>, but not able to do
data-help="home-help" data-redirect="home-redirect" in <a> tag.
Any help would be greatly appreciated!
link_to accepts a hash :data => { :foo => "bar" } of key/val pairs that it will build into data- attributes on the anchor tag. The above will create an attr as follows data-foo="bar"
So you could write a method on the model to grab self.data_fields (or whatever it's called) and split it into attr pairs and then create a hash from that. Then you can just pass the hash directly to the :data param in link_to by :data => model.custom_data_fields_hash
This somewhat verbose method splits things out and returns a hash that'd contain: {"help"=>"home-help", "redirect"=>"home-redirect"}
def custom_data_fields_hash
# this would be replaced by self.your_models_attr
data_fields = 'data-help="home-help" data-redirect="home-redirect"'
# split the full string by spaces into attr pairs
field_pairs = data_fields.split " "
results = {}
field_pairs.each do |field_pair|
# split the attr and value by the =
data_attr, data_value = field_pair.split "="
# remove the 'data-' substring because the link_to will add that in automatically for :data fields
data_attr.gsub! "data-", ""
# Strip the quotes, the helper will add those
data_value.gsub! '"', ""
# add the processed pair to the results
results[data_attr] = data_value
end
results
end
Running this in a Rails console gives:
2.1.2 :065 > helper.link_to "Some Link", "http://foo.com/", :data => custom_data_fields_hash
=> "<a data-help=\"home-help\" data-redirect=\"home-redirect\" href=\"http://foo.com/\">Some Link</a>"
Alternatively you could make it a helper and just pass in the model.data_attr instead
link_to "Some Link", "http://foo.com/", :data => custom_data_fields_hash(model.data_fields_attr)
Not sure you can directly embed an attribute string. You could try to decode the string in order to pass it to link_to:
- link_to model.link_name, model.url,
{
:class => model.class
}.merge(Hash[
str.scan(/([\w-]+)="([^"]*)"/)
])
)
var errorList = "<%= object.errors.messages.to_json %>";
In the above code object.errors.messages stores the Hash value as shown below.
{
:username => [
"can't be blank",
"is too short (minimum is 8 characters)"
],
:first_name => [
"can't be blank"
],
:last_name => [
"can't be blank"
],
:email => [
"can't be blank",
"is invalid"
],
:secondary_email => [
"can't be blank",
"is invalid",
"has already been taken"
],
:password => [
"can't be blank"
]
}
I want to access this hash value in javascript as a json object so that i can access each error messages conveniently (for ex errorList.username, errorList.first_name etc).So i am trying to convert that hash value into json and assign it to the errorList variable.So that i can access the error messages(for ex errorList.username, errorList.first_name etc).
<%= object.errors.messages.to_json %>" /*here i am trying to convert hash value into json
But i am not able to do that using above code, tell me the errors in that code if any, Otherwise tell me how can i access the hash value in ruby as a json in javascript.
Thank You.
You are passing the json as a string, javascript has no idea it is json. Also, the string is not html_safe, so ruby will try to escape it. You need to tell rails it is safe and parse it:
var errorList = JSON.parse("<%= object.errors.messages.to_json.html_safe %>");
However this is not the best way to do this. There is a very nice gem called gon. It allows you to pass ruby variables to your javascript easily and will move this logic from your view to your controller.
# controller
gon.errorList = object.errors.messages
# javascript
gon.errorList #=> {"username": ["can't be blank", ....], ...}
I have an array:
array = ["10", "20", "50", "99"]
And I want to convert it into a simple comma-separated string list like this:
"10", "20", "50", "99"
array.join(',') will almost do what you want; it will not retain the quotes around the values nor the spaces after.
For retaining quotes and spaces: array.map{|item| %Q{"#{item}"}}.join(', ')
This will print "\"10\", \"20\", \"50\", \"99\"". The escaped quotes are necessary assuming the question does in fact call for a single string.
Documentation on the %Q: string literals.
You could use inspect as suggested in another answer, I'd say that's personal preference. I wouldn't, go look at the source code for that and choose for yourself.
Useful aside: array.to_sentence will give you a "1, 2, 3 and 4" style output, which can be nice!
["10", "20", "50","99"].map(&:inspect).join(', ') # => '"10", "20", "50", "99"'
Here:
array.map {|str| "\"#{str}\""}.join(',')
Several answers have offered solutions using #map, #inspect, #join. All of them fail to get certain details of CSV encoding correct for edge cases involving embedded commas and/or string delimiters in the elements.
It's probably a better idea to use the stdlib class CSV then to roll your own.
irb> require 'csv'
=> true
irb> a = [10,'1,234','J.R. "Bob" Dobbs',3.14159]
=> [10, "1,234", "J.R. \"Bob\" Dobbs", 3.14159]
irb> puts a.to_csv
10,"1,234","J.R. ""Bob"" Dobbs",3.14159
The map.join solutions are sufficient if this encoding doesn't need to care about embedded delimiters, or is intended for some internal representation only, but they will fail if generating data for exchange with other programs that expect Comma Separated Values (CSV) as a generally understood representation.
The simplest solution is to use the built in ".to_sentence" method.
So
["fred", "john", "amy"].to_sentence outputs "fred, john, and amy"
This is a slightly alternative solution, particularly handy if you need to convert an array with double quoted strings to a single quoted list (for say SQL queries):
"'#{["John Oliver", "Sam Tom"].join("','")}'"
to
'John Oliver', 'Sam Tom'
Attribution: https://alok-anand-ror.blogspot.com/2014/04/ruby-join-array-elements-with-single.html
This is how you can send push notifications using FCM for Android devices.
Assuming you want notify followers when ever a user posts something on their status this is how you do it. This is done in Rails 5.2.6 for Rest Apis--- But still you can use the same for web push notifications. This is for sending to many devices with registration_ids to target followers with notifications.
Gem : fcm
in your controller:
require "fcm"
def create_vibe(user)
#vibe = user.vibes.new(content: #content, picture: #picture, video: #video, isvideofile: #isvideofile, video_thumbnail: #video_thumbnail, source: #source, background_color: #background_color)
#followed = user.followers
if #followed.present?
#registration = #followed.map { |s| s.registration_id }
end
if #vibe.save
fcm = FCM.new("") # set your FCM_SERVER_KEY
options = {
data: {
notification_type: 1,
title: "#{#vibe.user.username} " "has posted a new Vibe",
body: "#{#vibe.content}",
user_data: {
vibe_id: #vibe.id,
user_id: #vibe.user.id,
background_color: #background_color,
},
},
}
response = fcm.send(#registration, options)
puts response
render :status => 200,
:json => { :success => true,
:info => "Vibe posted successfully",
:vibe_info => {
:content => #content,
:picture => #picture,
:video => #video,
:video_thumbnail => #video_thumbnail,
:isvideofile => #isvideofile,
:source => #source,
:fcm => options,
} }
else
render :status => 200, :json => { :success => false, :result => "Vibe can't be blank" }
end
end