Oliver Azevedo Barnes
Rails Dev, telecommuting from São Paulo, Brazil
Posts
I've left my job at Gonow to go after personal projects, and am looking for a part-time contract gig to pay them bills.
Interested in any fun projects involving ruby, js, apis, and following tdd/bdd.
You get a very experienced dev with:
- seven years programming in ruby
- enough js and a little node
- project management and agile experience.
- a strong care for the big picture and ux.
- an eclectic and international background
I am going North soon (US and possibly Europe), and would love to spend time on location getting into the flow of a project and team, to then continue work remotely from São Paulo (gmt -3) after that. I know most companies hate remote... I'm good at it though, it won't hurt that much.
AND I can help you get into the Brazilian market.
For more details, add me up on linkedin.
I have a rails 3 project that, just to get started on editing it, I go through this whole process:
- start a mongodb server
- launch Redcar (cool all-ruby open source text editor)
- start Spork (for testing speed)
- start a rails server
- run the cucumber and rspec test suite for the first time
- open localhost and heroku dev site on Chrome
After getting an urge to automate this a dozen times, each time dissuaded by the Internal Yak Shaving Police, I finally got down to it.
2 minutes of googling led me to iTerm 2's applescripting docs and later to this post on applescripting Chrome. From the examples on both I put my own little script together:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
-- open terminal sessions tell application "iTerm 2" activate set myterm to (make new terminal) tell myterm -- start mongo launch session "Default" tell the last session write text "cd ~/Projects/killerapp; bundle exec rake mongo:start" end tell -- start redcar launch session "Default" tell the last session write text "cd ~/Projects/killerapp; redcar ." end tell -- wait for mongo to finish starting up delay 5 -- start server launch session "Default" tell the last session write text "cd ~/Projects/killerapp; rails server" end tell -- start spork launch session "Default" tell the last session write text "cd ~/Projects/killerapp; bundle exec spork cucumber & bundle exec spork &" end tell -- now wait for spork to finish starting up delay 20 -- run tests for the first time launch session "Default" tell the last session write text "cd ~/Projects/killerapp; bundle exec cucumber ; bundle exec rspec" end tell end tell end tell --way for server to finish starting up delay 10 -- open localhost and dev site on chrome tell i term application "Google Chrome" activate set mywindow to (make new window) tell active tab of mywindow set URL to "http://localhost:3000/" end tell tell mywindow set newTab to make new tab with properties {URL:"http://killerapp.heroku.com/"} end tell end tell |
Pretty basic so far, but it works. I use it as a template for other projects with similar initial flows.
Got any applescripts for your own Rails flow, or suggestions to improve this script? Shoot away in the comments
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class OpeningHours include MongoMapper::EmbeddedDocument [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday].each do |weekday| class_eval <<-KEYS_AND_ACCESSORS key :#{weekday}_opening, :default => "CLOSED" key :#{weekday}_closing def #{weekday} #{weekday}_opening == "CLOSED" ? #{weekday}_opening : \"\#\{#{weekday}_opening\} - \#\{#{weekday}_closing\}\" end KEYS_AND_ACCESSORS end end class Store include MongoMapper::Document one :opening_hours end store = Store.create! store.opening_hours.build store.opening_hours.monday #=> "CLOSED" |
Just changed this blog's url from oliverbarnes.posterous.com to digiberber.posterous.com. Using the original for a personal mumbling's blog from now on.
If you prefer the personal mumblings (photography, politics, kvetchs in general), click here
Confused about i18n options in Ruby-land?
I can see how this situation is confusing without knowing some of the history of i18n/l10n libraries in Ruby. I should probably write a few words up on that, but for now I'll try to give a overview from my perspective:
Gettext is obviously the oldest player in this game and it inherits both strengths and weaknesses from its ancestry which is being invented for a C dominated world. It has most features one needs, comes with some tools support that others lack (like desktop po file editors) and is widely accepted in the so called enterprise world.
Gettext as such defines an API and there are basically two libraries that implement it in the Ruby world, the traditional Ruby Gettext packages by Masao Mutoh and the fast_gettext gem by Michael Grosser.
Ruby Gettext is quite powerful and ships a lot of features that you may or may not need. The fast_gettext gem on the other hand focusses on raw speed and is implemented as a shiny, modern code-style Ruby library that is easily hackable and the author is a very smart and supportive person. Out of the two I'd personally strongly recommend fast_gettext.
The I18n gem is the result of the joint effort of various Ruby i18n/l10n solutions that existed a few years ago and that all strived to supersede Gettext for various reasons at that point of time. The resulting I18n API is basically covering the requirements and usecases of all the i18n/l10n solutions involved at that time, including the API of Gettext. So, todays Ruby I18n API is a superset of Gettext's API from the early 90s.
Today the I18n gem is the official solution that is shipped with Ruby on Rails, but it is also the probably most popular one in the Ruby world in general.
The I18n gem also makes it very easy to extend the featureset and add things like caching, other storage mechanisms (like Gettext po files, database tables, key-value stores; storage defaults to plain Ruby files and YAML) etc. and it ships with a number of modules for that (but external or custom modules can easily be crafted, tested and integrated).
There are translation files for 70+ languages (locales) for strings used by Ruby on Rails (which are useful in other projects, too) maintained by the community.
I can not tell much about R18n except that it was invented right after I18n hit its first release and as far as I remember it originated from the Merb community. It seems to be rather strong in the Russian Ruby world, but I might be wrong with all these assertions.
So, unless you have a very good reason to pick any other solution I'd strongly recommend using I18n.
Then on the other hand that means nothing because I've been leading this project more or less since it was invented.
I hope this helps.
Muneeb recently joined the ERA team and is getting his Rails grokked, coming from a .Net background. It's interesting to get a fresh view, and to get asked questions that makes you take a closer look at the "canons".
Today he asked:
"In larger applications, where do we put business logic in rails? Models seems a good solution but models are usually against entities (or database tables). What if the logic encompasses multiple model objects? Putting it in controllers will really swell them up, no?
Do we end up adding another layer in between controllers and model which basically gets all the data from the model, applies the logic and transfers it to the controller ? if yes, where does it fit in the directory structure?"
I haven't done huge apps myself, and it's hard to respond without a concrete example, but here's my take:
I'd say the way to deal with increasing complexity is to constantly modularize, always keeping it simple and within MVC - and specially, within REST.
I have this process in my mind:
Switch to thinking outside-in
From the view and then into the models. What's just enough to make the interface work? Thinking models before interface tends to make logic unnecessarily complex, trying to cover for all sorts of eventualities that many (most) times don't come true.
Break down your app into key restful resources
/products, /users, /tweets, /friends... Stuff that will get listed/read/written-to/destroyed from the view. This organizes things a lot, from the get go. One controller for each, all with their CRUD actions.
Figure out how these interact with others, and atomize interactions
Figure out who's the main actor (resource) in each interaction, the one the interaction is really about, and have this interaction happen in this resource's controller - but with all logic encapsulated in the model. This isn't always possible, of course - I'm thinking of shopping carts - and in this case you might create a new resource, /line_items for example, and repeat the process with it.
Whenever you start adding a lot of extra actions to your resource's controller, that's a smell - maybe time to consider refactoring those into a new resource. ...or lib
If a discrete piece of interaction gets complex, it can be factored out to /lib
and mixed into models or even controllers. When I say mixed-in, I mean composition. This is a big thing in Ruby: composition is preferred over inheritance. Much more flexible, and focused on how something acts, within a certain context, instead of what it is - which is a much messier question that can lead to both more rigidity and complexity.
If the app starts looking too big, might be worth breaking it down into separate apps
Tens of models, tens of controllers, many libs... Rack-integration makes it practical to integrate with other apps. It's common to have a main Rails app with only the core biz logic and with a few rack apps plugged into the stream (like Warden, for auth), and delegating other pieces of functionality to Sinatra apps. Or, with jruby, even java web apps.
That's it, my modeling process, for what it's worth :)
From reading this over, I'm realizing that 'atomizing interactions' is a bit vague, and perhaps it's where the real rub lies.
Thoughts?
At Engine Room Apps we’ve been developing a few web APIs to back our iphone apps. Learning how to test them has been an interesting experience, and since there aren’t that many examples online (that I know of, at least), here’s the lowdown:
We started out by testing xml output in controller tests using Test::Unit, asserting the existence of each tag and their attributes. We figured, since there weren’t any web views to test, the best place would be to test the controller. That worked alright, but it’s very verbose, and prone to holes in the coverage, specially when dealing with more complex xml structures.
For the next project I decided to look for other ways to accomplish this, and came across Chargify’s docs, which show their Cucumber features and include examples of their API’s xml output. Here’s one:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Scenario: Retrieve a customer via my reference id (as an integer or simple string) Given I have a customer with these attributes | reference | first_name | last_name | email | | 7890 | Joe | Blow | joe@example.com | When I send a GET request to https://[@subdomain].chargify.com/customers/lookup.xml?reference=7890 Then the response status should be "200 OK" And the response should be the xml: """ <?xml version="1.0" encoding="UTF-8"?> <customer> <id type="integer">`auto generated`</id> <first_name>Joe</first_name> <last_name>Blow</last_name> <email>joe@example.com</email> <organization>ABC Corp.</organization> <reference>777</reference> <created_at type="datetime">`auto generated`</created_at> <updated_at type="datetime">`auto generated`</updated_at> </customer> """ |
They have a step sending a request to the API’s endpoint, and then just test the whole output in a multiline string :) Right away, I wanted to switch to this approach. I didn’t know how to implement that step though, so I posted a question on stackoverflow (those reputation points just get you addicted), and it turns out the solution is pretty simple and elegant:
1 2 3 4 5 |
Then /^I should see the following output$/ do |xml_output| response = Hash.from_xml(page.body) expected = Hash.from_xml(xml_output) expected.diff(response).should == {} end |
Just convert both the xml example and the response to hashes, and diff them.
On another project we decided to switch to JSON responses, and you can test them in a similar way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#step Then /^(?:|I )should see JSON:$/ do |expected_json| require 'json' expected = JSON.parse(expected_json) actual = JSON.parse(page.body) expected.should == actual end #in the feature Then I should see JSON: """ [ { "name":"Oakland Models", "address":"Barnstones West Street, Clipsham, Rutland", "postcode":"LE15 7SJ", "services":[ { "name":"Model Store" }, { "name":"Mail Order" }, { "name":"Selected Club Membership Discount" } ] } ] """ |
Both have worked well for us, though JSON output proved to be a little more finicky than XML, surprisingly.
There’s a third way that’s perhaps worth mentioning (haven’t tried it yet), which would be to use Rspec 2’s request specs. They integrate Rails' built-in integration tests:
1 2 3 4 5 6 7 8 9 |
#From rspec-rails readme on github describe "widgets resource" do describe "GET index" do it "contains the widgets header" do get "/widgets/index" response.should have_selector("h1", :content => "Widgets") end end end |
This might be a good way to complement the cucumber tests with more granular ones, when needed.
That’s it. Feel free to leave other API testing experiences in the comments, it’d be great to hear them.
Update
The Collective Idea devs just shared their rspec/cucumber helpers for testing json, bundled in a gem called json_spec which is looking good. Going to give it a go next time.
This one took me a while to dig out, and from a couple of different places, so I figure it might be useful to others looking to use the same setup:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
require 'rubygems' require 'spork' Spork.prefork do ENV["RAILS_ENV"] ||= "test" require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') ...cucumber and capybara requires... require 'database_cleaner' require 'database_cleaner/cucumber' require 'database_cleaner/mongo_mapper/truncation' DatabaseCleaner.strategy = :truncation end Spork.each_run do ActionController::Base.allow_rescue = false Before do DatabaseCleaner.start end After do DatabaseCleaner.clean end end |
In case you’re wondering, Spork is a test server that will make your Cucumber + Rspec tests run much, much faster. It’s a whole different experience with it. No more cmd-tabbing to twitter/facebook/your-favorite-procrastination-tool-here while you wait for them to run.
DatabaseCleaner is a gem that’ll ensure tests run on a clean slate each time, providing an automatic teardown.
Updates
-
Three quick Rails console tips http://t.co/uELHXcnX via @37signals
-
Estão vendendo uma casa de vila aqui do lado, em Pinheiros, boa para escritório. Interessados, liguem-me: 8147 5272. Estou de corretor :)
-
@mattwynne did you get any good load stresser suggestions?7 days ago from web | Reply, Retweet, Favorite
-
Netherlands first country in Europe with net neutrality « Bits of Freedom » http://t.co/x9mNILen
-
Writing the story of an API http://t.co/o3IQXWde
-
one of those ideas that seems obvious once you see it done, a candidate-matcher http://t.co/G9I3LBPs
-
and finally learning the difference between bind(), live() and delegate()... http://t.co/SsT9u5Mm
-
ok, finally learning rails.js now
-
Airbnb payout and fees system: opaque and greedy http://t.co/LaWtezRZ
Posts
I'm working on a micro-forum of sorts, whereby a quick (close to tweet-size) topic message is posted by a special user, which subscribers can respond to with like-sized messages of their own. Straightforward, no 'digging' or voting of any sort, just a chronological flow of responses for each topic message. But with high traffic expected.
We would like to flag topic messages according to the response buzz they atract, using a scale of 0 to 10.
Been googling for trend algorithms and open source community application examples for a while, and so far have gleaned two interesting references, which I don't fully grok yet:
Understanding algorithms for measuring trends, a discussion on comparing wikipedia pageviews using the Baseline Trend Algorithm, here on SO.
The Britney Spears Problem, an in-depth article on how to rank search terms, while processing large streams of data.
From the first I understand the need to check the slope in activity, and to balance the weight between two items that differ greatly in scale of activity. But how do I compare many items, growing in number quickly across time? And then, how do I break the items within "buzz grades" from 0 to 10?
The second reference is fascinating, but over my head at this point. From a first pass I've understood the need to keep memory usage stable while keeping counters and storing references to items if necessary. But I haven't figured a fitting algorithm for my specific use case from it, yet.
It's worth noting that I come from a non-computer-science and definitely non-statistics background. Please bear with me :) Any help and code samples (specially in Ruby) would be greatly appreciated.
Is there a way to have multiple users interact with a youtube player widget, at the same time?
The scenario would be this: say I create a page that's a "viewing room", with a youtube player embedded in it, to which I can invite other users. With 2 or 3 people logged in, they all can click on controls, playing, stopping, rewinding etc the video, and all can see each other's interactions.
Is this possible? The inspiration for this is this "multi-player piano":
We have a Rails app with a view that gets populated with data from a third-party API. Currently, this view uses a swf streamer to open a socket to the endpoints.
Recently, the API's provider has asked us to switch to long polling ajax calls, and to pipe requests through a proxy in our server.
We're considering using node-http-proxy, to take advantage of node's speed and concurrency handling in case we get high traffic. We're new to Node.js, though.
The other option we're looking at is using the Rails app itself to forward these requests, the advantage being that we could use the existing session handling.
We'd prefer to use node-http-proxy, as it seems the most elegant solution (and an opportunity to play with Node.js, of course ;), but haven't figured out how to integrate it with our app's sessions (activerecord session store on postgres).
Is there a way to do it? Are there any other auth/security/session-checking strategies using node-http-proxy in parallel with a Rails app?
Oliver
I want to get autotest to run Steak acceptance tests whenever one of my rails app's relevant files is changed. After studying Rspec's and Cucumber's own autotest configs, I'm trying the following mappings:
Autotest.add_hook :initialize do |at|
at.add_mapping(%r%^spec/acceptance/.*_spec.rb$%, true) { |filename, _|
filename
}
at.add_mapping(%r%^app/(models|controllers|helpers|lib)/.*rb$%) {
at.files_matching %r%^spec/acceptance/.*_spec.rb$%
}
at.add_mapping(%r%^app/views/(.*)/.*rb$%) {
at.files_matching %r%^spec/acceptance/.*_spec.rb$%
}
end
the first one works: whenever a Steak spec is changed, it gets run again.
but the second and third don't. changing any source files under the /app subdirectories just gets ignored.
what's the correct way to get these mappings to work?
thanks Oliver
How do I check the "Please fill out this field" message that appears above required fields when they're submitted empty?
Right now my cucumber scenario seems to ignore the empty field completely, submitting the form successfully.
(I'm validating the fields presence, and when submitting manually, the form does show the message)
We're using God to monitor our server processes, and were wondering if we should use something like Monit to make sure God gets up if something unexpected happens.
A quis custodiet ipsos custodes? conundrum :)
Googling for it didn't bring any mentions of this being done, which makes me think it's probably pretty rare.
Has anybody here seen a need for it?
Given
class Patient
include Mongoid::Document
embeds_many :notes
end
class Note
include Mongoid::Document
embedded_in :patient
end
class Diagnosis < Note
end
Is there a way to access a patient's diagnoses through a notes collection?
patient = Patient.new
patient.diagnoses << Diagnosis.new
patient.notes #=> #<Diagnosis...>
I managed to get this with non-embedded docs:
class Diagnosis < Note
belongs_to :patient
end
class Note
include Mongoid::Document
end
class Patient
include Mongoid::Document
has_many :notes
has_many :diagnoses
end
(Using STI here to later create Prescriptions and other types of notes and list them all together)
Looks like this version has been pulled from Rubygems, only beta.12 and beta.13 are listed:
http://rubygems.org/gems/sprockets
So you'd need to get the specific beta.2 branch from the repo, as Thariq suggests.
BUT, I'd probably go for one of the versions listed on rubygems - there must be good a reason why they were pulled ;)
I'm trying
client.update("testing annotations", {:annotations => [{'flag' => 'true'}].to_json})
which goes through, but when I fetch the resulting tweet using the client again, the Hashie object returned doesn't include the annotation anywhere.
what gives?
I'm using Twitter gem version 1.1.2, with rails 2.3
How do I stub an http request, like this one to the twitter api below, on a global scope so it's valid for all tests in a Test::Unit suite?
stub_request(:get, "https://api.twitter.com/1/users/show.json?screen_name=digiberber").
with(:headers => {'Accept'=>'application/json', 'User-Agent'=>'Twitter Ruby Gem 1.1.2'}).
to_return(:status => 200, :body => "", :headers => {})
This WebMock stub works within a TestCase subclass's setup() block, like
class MyTest < ActiveSupport::TestCase
setup do
stub_request(...)...
end
end
But doesn't get recognized if I put it within a global setup in TestCase itself:
require 'webmock/test_unit'
class ActiveSupport::TestCase
setup do
stub_request(...)
end
end
Which gives me the error:
NoMethodError: undefined method `stub_request' for ActiveSupport::TestCase:Class
I've also tried by patching the method def itself
def self.setup
stub_request(...)
end
but it doesn't work either.
Something similar happens when I use FlexMock instead of WebMock. Seems to be a scope problem, but I can't figure out how to go around it. Ideas?
This post on different ways to setup() and teardown() led me to just do
class ActiveSupport::TestCase
def setup
stub_request(...)
end
end
hadn't thought of declaring it as an instance method. :P
When iterating results, you can store them in model objects, which in turn map to tables in sql databases (mysql, postgres, oracle), or documents in nosql dbs like mongodb.
Tweaking an example in the twitter gem's README:
# Find and store the 3 most recent marriage proposals to @justinbieber
Twitter::Search.new.containing("marry me").to("justinbieber").result_type("recent").per_page(3).each do |r|
MyLocalTweetModel.create!(:from_user => r.from_user, :text => #{r.text}")
end
This can be done with any database, really.
The decision over which database to use depends on many other factors, such as where your app will be hosted, what traffic you expect, how you plan to scale it... and taste is definitely one of these factors, and not an unimportant one. I hate Active Record migrations, for instance, though I like its many other niceties. Active Record is the default ORM rails uses for sql databases.
If you're new to all this, just start on a simple sqlite database with Active Record. There's more of a learning-curve to the alternatives.
This discussion on the rails-i18n google group has an interesting solution:
#in a locale file
en:
education_levels:
gcses: Some GCSEs or less
collegeA: College A levels
some_university: Some University, no degree
bachelors: University graduate - Bachelors or equivalent
masters: Masters degree
professional: Professional Degree
doctorate: Doctorate
#And in a model:
class Education < ActiveRecord::Base
def translated_education_level
I18n.t(education_level, :scope => :education_levels)
end
end
#In a helper:
module EducationHelper
def education_levels
I18n.t(:education_levels).map { |key, value| [ value, key ] }
end
end
#And then in your view:
<%= f.select :education_level, education_levels %>
In the comments to the solution for How do I find an image on a page with Cucumber/Capybara, somebody asked:
I can't seem to figure how to get this to work with URLs generated by Dragonfly. They look like this: /media/BAh_some_long_string_AwIw/12_11_52_810_5x5.jpg?s=7e360000, where 5x5.jpg is my file name. I've tried something like: //img[@src="/media//#{image}?s=*"] but it doesn't work. Got any tips? – Ramon Tayag Feb 25 at 4:18
I have a similar problem, only worse - in my case, the generated image paths don't even include a (jpg|png|gif) file name, they only have these really long ids:
<img src="/media/BAhbB1sHOgZmSSIdNGQ4MTEyOGU3ZjViZmQwZTQ4MDAwMDAyBjoGRVRbCDoGcDoKdGh1bWJJIg0yMDB4MjAwIwY7BlQ" />
(Using dragonfly with mongo/gridfs)
These paths get rendered alright, but I can't figure out how to find them in a Cucumber/Capybara step :P
Any ideas? I looked at the Dragonfly's features, but they only test the rendering of the image itself, without detecting it's existence within an html page.
Answering my own question, after talking to Dragonfly's author (he's working on making this easier):
#route
match '/media/:dragonfly/:file_name', :to => Dragonfly[:images]
#model
class Store
include MongoMapper::Document
key :photo_uid, String
key :photo_name, String
image_accessor :photo
end
#view
<%= image_tag @store.photo.thumb('274x207#').url(:suffix => "/#{@store.photo_name}") if @store.photo %>
#cucumber
Then I should see the image "my_photo.png"
Then /^I should see the image "(.+)"$/ do |image|
page.should have_xpath("//img[contains(@src, \"#{image}\")]")
end
The key is adding an [attachment]_name field to the model, which Dragonfly populates automatically, and then passing it on as a suffix to url(). And the routes needs to allow for a :file_name param besides the generated dragonfly identifier.
Say I have a formtastic form that creates a Store and allows selection of Services it provides:
<%= semantic_form_for @store do |f| %>
<%= f.inputs :services, :as => :check_boxes, :collection => Service.all %>
<%= f.buttons %>
<% end -%>
I want to allow the user to add a new Service in case he doesn't see it in the options, right from the form.
There are many examples for simple nested form element addition, say of a Task entry to a Project, and even a gem that helps with this, but I haven't found any that create a new resource so it'll show as part os checkbox or select options.
Got it working this way:
<%= semantic_form_for @store do |f| %>
<%= f.inputs :services, :as => :check_boxes,
:collection => Service.all,
:wrapper_html => { :id => 'service_fields' } %>
<%= f.buttons %>
<% end -%>
Added an id to the parent list item around the checkbox field listing, so it can be accessed by this js after submitting a text field with the new service name:
<input type="text" id="new_service_name" />
<input type="button" value="ok" id="btnSave" />
<script type="text/javascript">
$(document).ready(function() {
$('#btnSave').click(function() {
$.ajax({
url: '/admin/services.json',
type: 'POST',
dataType: 'json',
data: 'service[name]=' + $('#new_service_name').val(),
success: function(data) {
addCheckbox(data);
}
});
});
});
function addCheckbox(name) {
var container = $('#service_fields fieldset ol');
var inputs = container.find('input');
var id = inputs.length+1;
//var html = '<input type="checkbox" id="cb'+id+'" value="'+name+'" /> <label for="cb'+id+'">'+name+'</label>';
var html = '<li><label for="store_services_'+id+'"><input id="store_services_'+id+'" name="store[services][]" type="checkbox" value="'+id+'" />'+name+'</label></li>';
container.append($(html));
}
</script>
Then, in ServicesController:
class ServicesController < ApplicationController
respond_to :json
def create
service = Service.create!(params[:service])
respond_with(service)
end
end
The following formtastic form checkbox field set:
<%= semantic_form_for @store do |f| %>
<%= f.inputs do %>
<%= f.input :services, :as => :check_boxes, :collection => Service.all %>
<% end -%>
<% end -%>
is sending bad params for :services on a Cucumber test using Capybara, making the test fail, while the actual app sends the correct ones, which gets processed fine:
#cucumber steps using the boiler_plate capybara web_steps.rb:
Given a "Mail Order" service
...(steps for rest of the form)...
When I check "Mail Order"
And I press "Create Store"
Then I should see "Store was successfully created."
And I should see "Mail Order"
#params sent by cucumber
"store"=>{"services"=>["[\"4d8247ed7f5bfd2275000004\"]"]
#params sent by app on manual test
"store"=>{"services"=>["4d8247ed7f5bfd2275000004"]}
Though the html form itself is rendered the same way in both cases:
<input id="store_services_4d8247ed7f5bfd2275000004" name="store[services][]" type="checkbox" value="4d8247ed7f5bfd2275000004" />
Seems like somewhere during the request params-building, the form key/value pairs for that field get parsed differently when submitted by Cucumber/Capybara.
Anyone else come across this?
Answering my own question:
Got a pointer from Capybara's author, Jonas Nicklas, that led me to this rack-test patch which hasn't been committed yet
For now I'm just using the fork and branch where the patch lives:
gem 'rack-test', :git => 'https://github.com/econsultancy/rack-test.git', :branch => 'econsultancy-20110119'
And that does the trick. I imagine this patch will be merged in very soon though, as it was submitted a couple of months ago.
I need to make a site's menu navigate like OSX's Finder in column view, where each level appears next to its parent in a vertical column.
Have been googling this for a couple of hours now, and this Jquery plugin seems to be the closest match (There's a demo here)
From a first trial, it seems somewhat hard to customize. I need it to behave and look differently in a couple of ways:
- no scrolls, neither vertical nor horizontal. it needs to act more like a web menu than like a select box
- when clicking on the final link, after navigating the subs, the whole page should be redirected to the url, and the menu should keep the state.
- the final link should be clickable right away, like on the demo. on my trial, it loads yet another column with a duplicate of the link, which in turn is clickable.
Does anybody know how to accomplish these with this plugin, or could point me towards simpler implementations that are closer to these specs?
Here's the menu html structure:
<ul id="nav">
<li class="current" id="nav-o-que-estamos-fazendo">
<a href="/o-que-estamos-fazendo/">O que estamos fazendo</a>
<ul id="nav-o-que-estamos-fazendo-children">
<li id="nav-o-que-estamos-fazendo-children-ficcao">
<a href="/o-que-estamos-fazendo/ficcao/">Ficção</a>
</li>
<li class="current" id="nav-o-que-estamos-fazendo-children-documentario">
<a href="/o-que-estamos-fazendo/documentario/">Documentário</a>
<ul id="nav-o-que-estamos-fazendo-children-documentario-children">
<li class="current" id="nav-o-que-estamos-fazendo-children-documentario-children-josephine-king">
<a href="/o-que-estamos-fazendo/documentario/josephine-king/">Josephine King</a>
</li>
</ul>
</li>
<li id="nav-o-que-estamos-fazendo-children-televiso">
<a href="/o-que-estamos-fazendo/televiso/">Televisão</a>
</li>
<li id="nav-o-que-estamos-fazendo-children-museus">
<a href="/o-que-estamos-fazendo/museus/">Museus</a>
</li>
</ul>
</li>
<li id="nav-o-que-ja-fizemos">
<a href="/o-que-ja-fizemos/">O que já fizemos</a>
</li>
<li id="nav-o-que-somos">
<a href="/o-que-somos/">O que somos</a>
</li>
<li id="nav-quem-somos-contato">
<a href="/quem-somos-contato/">Quem somos | contato</a>
</li>
<li id="nav-mirabolancias">
<a href="/mirabolancias/">Mirabolâncias</a>
</li>
</ul>
As generated by the 'nav' liquid tag on Harmonyapp)
With the following Store and Service models, managed with MongoMapper:
class Store
include MongoMapper::Document
key :service_ids, Array, :typecast => 'ObjectId'
many :services, :in => :service_ids
end
class Service
include MongoMapper::Document
key :name, String
many :stores, :foreign_key => :service_ids
end
I have this form, done with Formtastic:
<%= semantic_form_for @store, :url => admin_store_path(@store), :method => :put do |form| %>
<%= form.input :service_ids, :label => "Select Store Services",
:as => :check_boxes,
:collection => Service.all %>
<% end -%>
The controller uses Inherited Resources, and the edit action is implicit.
When editing a @store with services already associated with it, the checkboxes for the latter don't show as checked.
Formtastic's README warns it doesn't support MongoMapper officially, but it also says people have been using both together successfully, and I've seen some examples of this online.
I suspect Inherited Resources also doesn't support it, from what I've seen from Devise + Simple Form, both from the same authors and which don't support MM. They're working towards using an ORM adapter in their gems, but it isn't ready yet AFAIK.
And I've had problems with it already, I'm overriding the update action to get it to work:
def update
store = Store.find(params[:id])
if store.update_attributes!(params[:store])
flash[:notice] = 'Store was successfully updated.'
redirect_to admin_store_path(store)
else
redirect_to new_store_path
end
end
Does anybody know where the conflict with MM is, either in Formtastic or IR, and a hack just to get these checkboxes checking?
From reading the db:test tasks's source, it looks like they only care about grabbing the test db info from database.yml, but don't care which actual environment they're doing it under.
You might need to run rake db:test:prepare RAILS_ENV=test to ensure you're under the test environment.
One way might be to dump the dev data to yaml (this plugin does that and there are probably others that will do the trick), and then use db/seeds.rb to write a script loading its contents and using rails models to recreate them on the production db with rake db:seed
rake db:seed won't hose your data (it just loads db/seeds.rb, see the source here and here), but be sure to backup your data before anything :)
I'd suggest playing with a sandbox app and db clone before going ahead and running this on production.
Try
ActiveResource::Base.include_root_in_json = false
If you need to keep the top root and just remove the associated credit card object's root, then you might need to customize the json output with #to_json, like this:
def to_json(options = {})
{ "user"=>
{"credit_card"=>
{"number"=> self.credit_card.number }
},
"user_name"=> self.user_name
}.to_json(options)
end
From that picture, I'm understanding you just want to exclude them from the coverage analysis?
If so, something like this might help:
http://psixty.wordpress.com/2010/06/22/how-to-exclude-files-in-rcova-code-coverage-tool-in-ruby/
I'd suggest using uploading a fixture image, as per this other SO thread
One way would be to avoid hitting the API at all, by faking the responses with Fakeweb
This will speed up your tests :) And decoupling them from external services is a Good Thing in general - saves bandwidth, ensures your tests will run if the service is down, etc
snapshot is set as a local variable in controller, so the template doesn't see it. Set it as an instance variable:
@snapshot = Snapshot.find(params[:id])
then in the template:
:locals => {:snapshot => @snapshot
Are there any implementations (open source or proprietary) of TinyMCE-like widgets for iOS apps?
If not, are there any references, tutorials, recipes etc no how to roll one's own?
Try
<% if f.object.is_white == true %>
Seem to remember you could access the object this way (not 100% sure though ;)
is Api::LoginController being described higher up on the describe chain? I wonder if ActionController::TestCase::Behavior is being mixed in. can you access controller.session?
what doesn't work exactly? is the session helper not working at all, or just is it that session[:msg] isn't set? what does session.inspect give you?
@Tonys there is, and when submitting manually the message appears.
@AndyWaite the default, from looking at the capybara README just now it looks like it's :rack_test. and it doesn't support javascript, which I didn't expect. so the answer would be to use a js driver?
makes sense. so upstart would be closer to the core than using service?
I see many questions about deployment on stackoverflow (like this one), and it's a common task for rails devs. Perhaps this is a question that belongs on both?
None of the three answers work for you?
it'd be good to see the routes + controller
It depends, are you testing an interface of an html editor? if so, it could be correct ;)
...I mean I'm just adding the stub call in the wrong place, where the mocking libs don't get recognized. I can't figure out where the correct place would be, or how to force the inclusion of those stubbing/mocking methods there. Tried FlexMock.flexmock(), for instance, just but Flexmock module just isn't there, though it's required (tried include()ing it, but no luck either)
@Wizard of Ogz, actually that was my original approach - stubbing twitter gem's Twitter.user() with flexmock under global setup(). But flexmock() also doesn't get recognized :P. I think in both approaches I'm just stubbing in the wrong place, but can't figure out the correct one
wouldn't fakeweb have the same issue? register_uri() is very similar to webmock's stub_request(), and I'd need to run it globally as well
it returns Hashie::Mash objects
thanks for posting this, it's a worthy option
Profile
Summary
I enjoy working in projects that value elegant design and best-practices, while providing good, flexible working conditions.
Interested in the exploratory nature of startups, agile methodologies and entrepreneurship - minus the bs.
Experience
- Apr 2012 - PresentFounder, Lead Dev / 3Bounce
- Apr 2012 - PresentWeb App Developer and Consultant / oliverbarnes.com
- Aug 2011 - PresentRuby Developer / GoNowJanuary '12 - present - allocated to Coinvalores (brokerage firm). Stealth app development and tuning, consulting on planning and development processes. December '11 - allocated to Bio-Ritmo (fitness chain), tuning their academy management apps for performance September - November '11 - allocated to Editora Abril, working on their web publishing system backing their magazines' sites, and then on http://iba.com.br/, their digital subscription service. August '11 - worked on last stretch of development and delivery of a high traffic web game for a major European client.
- Sept 2010 - PresentRails Developer / Engine Room AppsDevelopment and deployment of Ruby on Rails APIs and admins for iOS applications, and baby-sitting them up on Heroku. Participation on honing development processes and methodologies, pushing for the introduction of best-practices like TDD/BDD and outside-in development.
- Feb 2008 - PresentPartner, Developer / Gordo & Barnes SoftwareDevelopment of software as a service (SaaS) apps and customization of open source apps for other businesses, using Ruby on Rails.
- Feb 2009 - PresentPartner and Developer / Portal JurídicoDevelopment of a SaaS product targeting the Brazilian real-estate law market.
- Sept 2000 - PresentIndependent Web Developer / oliverbarnes.comConsulting, implementation and customization of ecommerce, institutional websites of all sorts, and development of custom web applications.
- Oct 1999 - PresentUser Interface Developer / Boyle SoftwareWorking at Columbia House online as a subcontractor. Mockup slicing, HTML, CSS, Javascript coding. some Applescript, some Perl, some PHP as well.
- Sept 1998 - PresentTechnical Producer / StarmediaMockup slicing, HTML, CSS, Javascript coding, integration with Python and Vignette StoryServer backends.
Education
-
1993 - 1998Universidade de São PauloBachelor in History
-
1989 - 1993Chapel School
-
1989 - 1993Escola Maria Imaculada (Chapel)
-
1988 - 1989Graded School
Additional Information
Posts
Fotos de Hitler junto com fotos de prisioneiros de guerra, algumas incríveis, em um álbum caseiro.
Não se sabe quem tirou. A história de como o álbum chegou ao NYT é muito boa:
He said the photo album and 50,000 baseball trading cards were given to him by a manual laborer of his acquaintance who had fallen on hard times and had to borrow money from the executive. The objects amounted to repayment of the cash loan. The executive said the worker told him he had received the album from an old German man whose lawn he had maintained. Because there are nine pictures of Hitler in the 24-page album, all who handled it were sure it must have some value.
Updates
-
EUA podem ajudar Brasil a abrir 'caixa de Pandora' da ditadura http://t.co/cPHueb5d
-
"Olha, está meio nebuloso hoje viu" http://t.co/kSgxBW0a do diretor do kassab, sobre seus 106 imóveis
-
@marcelorubens muito bom.
-
Estão precisando de web designer na @promenino http://t.co/IPSie5Y0
-
Policiais americanos da fronteira com o México demitidos por apoiar o fim da guerra contra as drogas http://t.co/hXStyDhY
-
http://t.co/novq35bS - Law Enforcement Against Prohibition5 months ago from web | Reply, Retweet, Favorite
-
trust the internet will connect the dots http://t.co/EF9CiFCP ...somehow
-
@sapeando esse aqui é o meu twitter pessoal, o @digiberber é pra programação6 months ago from web | Reply, Retweet, Favorite
-
mas o que seria equivalente aqui no Brasil? nunca ouví falar de pequenos bancos locais nem de cooperativas de crédito aqui6 months ago from web | Reply, Retweet, Favorite
-
e outro parecido http://t.co/1j2tdQjI - marcado pra hoje6 months ago from web | Reply, Retweet, Favorite
-
http://t.co/psv85kYi projeto da Arianna Huffington para migrar o dinheiro dos grandes bancos para cooperativas e bancos locais6 months ago from web | Reply, Retweet, Favorite