-
Deploy Ruby on Rails Tutorial (link)
As someone that finds it hard to make the time to post regularly, I am totally impressed with this tutorial for setting up a Rails server: Props to Ruby Tree Software !!! Deploy Ruby on Rails Tutorial …
-
RailsBridge Phoenix - Ruby on Rails for Women
OK, everybody, it is time for us to give back to the Ruby/Rails community that has made many of us a enjoyable and profitable life.... We at Socialwhirled have decided to sponsor and host a RailsBridge event in Phoenix (http://railsbridge.org/) the 19th and 20th of September. From their site:
We teach people to code because we believe that the people making technology should accurately reflect the diversity of those using it. We want to push for all kinds of diversity in tech: gender, race, sexual orientation, ability, and class. Women were the first population we focused on, but aren't the last. We value acceptance, enthusiasm, and hard work. The RailsBridge community thrives on optimism and a love for making great things. What's a RailsBridge Workshop? Our most well-known efforts are free weekend workshops where women learn Ruby on Rails from volunteers. The students at our workshops range from folks who are completely new to programming to QA engineers and professional developers who want to learn Rails. During the Installfest (usually on a Friday evening), we get students' laptops setup with the requisite technologies. The next day, we break into small group based on experience level and build a web app! (When we aren't teaching Ruby and Rails, we teach HTML & CSS.)
Here is what we need: Volunteers to assist in teaching as well as TA'ing. I think we will need about 8 people that can teach a class using their curriculum and assistants to help attendees that are stuck. Attendees to attend. Spread the word to friends, strangers, social media, etc... I will post the links as soon as I have them setup. All social media should use the #railsbridge and #railsbridgeaz hashtags. Most of us learned form others so lets return the favor. Questions, comments, suggestions, want to volunteer, email me at broberts@socialwhirled.com …
-
Rail Unicorn server start on server boot
So this weekend we were having some power outages where our onsite servers are located. When the servers booted back up, Unicorn server was not running. This was quick and easy to fix using the capistrano-unicorn gem:
If you get a generic looking 500 page then it may be the Unicorn server. You can check if Unicorn is running using ps aux as well. There should be one master and 5 workers running. If not you can use: cap unicorn:reload # Reload Unicorn
But that is a reactive fix and we want to be proactive and not think about these things on the weekend. So, I tried a few other things like Monit but I could not get it to play nice with Unicorn and even then I realized that there was nothing setting Monit to start on server boot. I read a couple of things about Bluepill gem and I decided to give it a try. First off I added the Bluepill gem to my Gemfile but that did not seem to work so I installed on the server:
cap unicorn:restart # Restart Unicorn
cap unicorn:show_vars # Debug Unicorn variables
cap unicorn:shutdown # Immediately shutdown Unicorn
cap unicorn:start # Start Unicorn master process
cap unicorn:stop # Stop Unicorn Remember to use the development/staging/production in between the cap and unicorn (e.g. cap development unicorn:stop) In general, I would just use stop and start. It gives pretty good errors when you run it.sudo gem install bluepill Following the Github README, I created /var/run/bluepill directory for bluepill to store its pid and sock files. Next I created a Bluepill configuration file in path/to/app/config and named it production.pill. Bluepill can use different pill files based on the environment. [sourcecode language="ruby"] Bluepill.application("my_app", log_file: "/var/www/my_app/shared/log/bluepill.log") do |app|
app.process("unicorn") do |process|
process.working_dir = "/var/www/my_app/current" process.start_grace_time = 20.seconds
process.stop_grace_time = 20.second
process.restart_grace_time = 20.seconds process.pid_file = "/var/www/my_app/shared/pids/unicorn.pid" process.start_command = "bundle exec unicorn -c /var/www/my_app/current/config/unicorn.rb -E production -D"
process.stop_command = "kill -QUIT "
process.restart_command = "kill -USR2 " process.uid = "deploy"
process.gid = "deploy"
end
end [/sourcecode] We will want to test to see if Bluepill is working. First we need to load the Bluepill configuration file and start it:$ sudo bluepill load /var/www/my_app/current/config/production.pill
$ sudo bluepill status Now we should have Bluepill monitoring our unicorn. I tested this by stopping the unicorn server and checking the application and sure enough, the Unicorn master was restarted by Bluepill. You can also watch the Bluepill logfile with sudo bluepill log unicorn. So now that is all up and running, we need to make sure that Bluepill is started when the server boots. Create a bluepill.cong in the /var/init/ directory and add this: [sourcecode language="ruby"] description "My App Bluepill" start on runlevel [2]
stop on runlevel [016] expect daemon
exec bluepill load /var/www/my_app/current/config/production.pill respawn [/sourcecode] …
-
Ruby time and Google Calendar API
So Google Calendar is pretty picky when it comes to working with its API. We have an application that will fetch the calendar events for a 2 month timeframe. It will soon be changed to allow for a different start and end time. So first of all lets look at what the URL must be formatted as:
https://www.googleapis.com/calendar/v3/calendars/test%40gmail.com/events?key=<your-api-key-goes-here>&timeMin=2014-06-11T12:00:00Z&timeMax=2014-08-12T12:00:00Z&orderBy=starttime&singleEvents=true So notice that the timMin is the calendars start time and is formatted as such:
2014-06-11T12:00:00Z This was a pain in the ass to convert correctly. I never was able to completely get the format correctly using Ruby strftime but I got really close:
Date.today.strftime("%Y-%m-%dT%l:%M:%S") == 2014-06-11T12:00:00 So I cheated and did:
Date.today.strftime("%Y-%m-%dT%l:%M:%S") + "Z" Now for the fun part. I just refactored older code. I just want to show the before and after for the fun of it!!! BEFORE: [sourcecode language="ruby"] def current_calendar
@cal = nil
@api_key = 'zzzzzzzz' @cc_today = Time.now
@cc_yr = @cc_today.year
@cc_mth = @cc_today.month # We want to get two mths of events
# so create a Time for next month
if @cc_mth == 12
@cc_mth = 1
@cc_yr += 1
else
@cc_mth += 1
end @cc_next_mth = Time.new(@cc_yr, @cc_mth, 1)
@days_in_month = Time.days_in_month(@cc_mth) @min_date = '%Y-%m-01'
@max_date = '%Y-%m-'
@max_date = @max_date + @days_in_month.to_s
@timeMin = @cc_today.strftime(@min_date)
@timeMax = @cc_next_mth.strftime(@max_date) @timeMin = @timeMin + 'T00:00:01Z'
@timeMax = @timeMax + 'T23:59:59Z' @myString = '?'
@myString = @myString + 'key='
@myString = @myString + @api_key
@myString = @myString + '&'
@myString = @myString + 'timeMin='
@myString = @myString + @timeMin
@myString = @myString + '&'
@myString = @myString + 'timeMax='
@myString = @myString + @timeMax
@myString = @myString + '&'
@myString = @myString + 'orderBy=starttime'
@myString = @myString + '&'
@myString = @myString + 'singleEvents=true' @email = self.url.gsub(/@/ , '%40') @url_params = 'https://www.googleapis.com/calendar/v3/calendars/'
@url_params = @url_params + @email
@url_params = @url_params + '/events'
@url_params = @url_params + @myString
@response = HTTParty.get(@url_params)
@cal = @response.parsed_response['items']
end
[/sourcecode] AND AFTER: [sourcecode language="ruby"] def current_calendar
api_key = 'zzzzzzzzz' time_min = Date.today.strftime("%Y-%m-%dT%l:%M:%S") + "Z"
time_max = (Date.today + 2.months + 1.day).strftime("%Y-%m-%dT%l:%M:%S") + "Z" url = "https://www.googleapis.com/calendar/v3/calendars/#{self.url.gsub(/@/ , '%40')}/events?key=" +
api_key + "&timeMin=" + time_min + "&timeMax=" + time_max + "&orderBy=starttime&singleEvents=true" response = HTTParty.get(url)
@cal = response.parsed_response['items']
end [/sourcecode] Moral of the story .... Ruby is a fantastic language with methods for just about everything. Why do things the hard way??? …
-
Implementing Data Table In Rails
Nice writeup of using Datatables in Rails app. I use this gem myself in a CRM. Easy to use and looks great out of the box. I just wish it would work with mongodb :( …
-
Building a Rails shop from the ground up
This past week, I was given the opportunity of a life time. On Tuesday, I start my new position at SocialWhirled as Senior Developer and Team Lead. My first mission is to build an in-house team. I get to hire Rails developers and build A Rails shop here in Phoenix. And this will not be just any Rails shop, we will be the biggest and best Rails shop in the Southwest.
When I first got into Rails I heard names like Thoughtbot, Pivotal Labs and Intridea and hoped to one day work for one of them. I have followed their blogs and now, I have the ability to emulate these companies and make new Rails developers wish to someday work for Socialwhirled. I want others to look up to how we operate and wish that they too could work for us.
I cannot express my excitement. We literally have an opportunity to set up shop how we want it. Each and every new developer that joins our team will be a part of the building process. We will all decide on what tools we will use and what equipment we will want. I have had my frustrations in the corporate world be we are not even close to corporate and with the CEO's attitude, I don't think we will ever even be close to corporate. Granted that we are somewhat of a startup, we are solid enough to do things right.
If you have any ideas or suggestions for this, I would love to hear them.
It is going to be a fun ride ...
UPDATE June 25th
I am so happy to day that I have hired two guys to start building our Rails shop. Not only that but for the 3 of you that read my blog, you already know that I had a couple of interns a couple of years ago that were working jobs in the valley. Well it took some bribing but those guys now work with me. We also have our sights on two interns to add to the team as well.
It really makes me happy that I got to hire these guys. I watched both of them go from learning Rails to earning with Rails.
We are not done yet. Time to take over the world !! …
-
Tech recruiters; do we really need them?
OK, this post is for me to vent my anger at tech recruiters. Last year, I removed my LinkedIn account as I was sick of getting bombarded by recruiters. It is part of the business that we are lucky enough to be in; higher demand than supply. I do not have an issue with the polite recruiters that at least take the time to send an email that does not look cut and pasted and the job is at least related to abilities.
Now, when I get the Dear (candidate) ... that pisses me off. Or if I get a job offer for something completely not related to my abilities as listed on LinkedIn, that annoys me. I have received the same job listing as many as three times from the same recruiter. At that point I know that you are a lazy ass human and I will not deal with you and your blanket tech marketing. I have gotten the same email from the same recruiter every day for almost 2 weeks straight. No means no but that doesn't remove me from your hit list.
Recruiters get paid to place us. That is their job. Some will embellish or make shit up to get you to go to work somewhere. That has happened to me and I am sure many others.
Today, I got in a disagreement with a recruiter because I "was asking too much money!" What? You are just a recruiter. You don't determine my value. I gave up trying to justify my asking and that I was by no means going to take any less than my asking and hung up on her. I got a couple of calls from the company that I was applying to a few hours later and ignored them. I basically screwed myself out of a good position because I don't want to deal with that recruiter anymore and I thought that I was clear on that. She missed out on a pretty good commission.
So, how many of you have had good luck with recruiters? I do not think I will deal with them anymore. …
-
Pre-Caching a page in Rails
I recently had to figure out how to basically freeze a page in a rails app so that any changes to the dynamic data would not change the front facing view.
The app has a “web page” that is created dynamically and is then “published” to the web on a weekly basis. As this is always the same view, I needed to figure out how to save the view from each week. StackOverflow led me to the best option being to cache the page.
Easy enough, but what happens if nobody visits the page for one week? It is never cached. So after some googling I found that I could curl the page from the app and that cur (curl is a client to get documents/files from or send documents to a server, using any of the supported protocols (HTTP, HTTPS, FTP, GOPHER, DICT, TELNET, LDAP or FILE). The command is designed to work without user interaction or any kind of interactivity.) l would be sufficient enough to make the page cache.
I set the controller to caches_page on the show action. Then in the controller that performs the “publishing” I set it to clear the cached page. Nothing happened. I manually cleared the cache both in the project as well as in the browser and the page still displayed!
I finally found that the cached page was in my public folder and not the tmp folder. At first I thought that it was something that I set up incorrectly but then realized that it was how the page was setup in the first place. As this is a front facing page requiring no authentication it was named spaced in the controllers/public directory with the views in the /public directory. So that is why the cached pages were going to the public directory and not to the tmp directory as is the norm.
Now I had to manually find the cached copy and remove it.
As there really is not a need for the page to be instantly cached and no need to the user to wait for it, I moved it into a background job using Sidekiq.
So first I created a helper method to do some of the initial processing. To the controller that does the publishing I need to add a couple of things: [code language="ruby"] include CacheHelper ## this tells it to use the helper
update_web_cache ## this is called in the action to publish [/code] So when the user publishes it will call the CacheHelper: [code language="ruby"]
## file cache_helper.rb
module CacheHelper def update_web_cache
FileUtils.rm_rf(Dir["#{Rails.root}/public/path_to_cached_view.html"])
url = "#{ENV['HOSTNAME']}" + path_to_the_view_needed_to_be_cached
CacheWorker.perform_async(url)
end
end
[/code] First I had to manually remove the cached view and I did so using FileUtils. Then as this is in the helper I have access to my model and therefor I can get the path to the view based on the model. Last, I tell Sidekiq to do it's thing. OK, so to this point we have removed the old cache but now we need to create the new cache. After a lot more googling the only way I could figure out how to curl the page was with a rake task. Further down the rabbit hole... In the Sidekiq worker, I added the code to run the rake task. There were a few options to do this but I found the execute command to be the easiest and it worked. [code language="ruby"]
## file cache_worker.rb
class CacheWorker
include Sidekiq::Worker def perform(url)
%x(bundle exec rake curl["#{url}"])
end
end
[/code] This then takes the url that it is passed and runs the rake task: [code language="ruby"]
## file lib/tasks/curl.rake
desc "curl"
task :curl, [:url] => :environment do |task, args|
system "curl #{args.url}"
end
[/code] Bottom line, created a background job that calls a rake task to curl a page.
Now, if there is any easier way to do this I sure would love to know. …
-
Ruby on Rails testing with Select2
I posted a while back about using the select2-rails gem together with the select2-capistrano gem. I recently upgraded an app and found that my tests that were using select2 were all failing. I did some googling and it seems that the select2-capistrano gem is no longer active. Well, I went about it another way then. First off, I do not add the class to each drop-down select but rather I do it globally using a collection_select_input.rb file in app/inputs/ like so: [code language="ruby"]
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
def input_html_classes
super.push('chosen-select')
end
end
[/code] So when I started to have issues with capybara not being able to use the select2 drop-down my fix was to only use the global push if not in test environment: [code language="ruby"]
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
unless Rails.env.test?
def input_html_classes
super.push('chosen-select')
end
end
end
[/code] So now I have good old normal drop downs in test environment and the ever awesome select2 drop downs in production. …
-
Detecting IE browser in Rails app
I have been working an app that is used by many users that are still on MS XP and using IE8. It is a javascript heavy app and I have many issues in dealing with the cross-browser compatibility (IE) but today I found a great gem. I was trying everything using CSS to hide a div in IE 8 to no avail. And then Browser Gem to the rescue. I added a simple check for IE 8 in my view: = if browser.ie8? Thank you browser gem!!! …