Say what one more fucking time!*
So I recently inherited a Soundblaster audio card from a friend. In general I maintain that average people just cant hear the difference in good and bad sound, but I decided to install it in any event, just cause I can.
Or so I thought.
Enter the hell that is linux support for audio drivers. Fuck all worked.
I eventually (20 forum trawls later) settled on trying to install OSS, which proceeded to break what sound I had before I started.
So, out with the Soundblaster and remove what I could of the changes. Still no sound. My Logitect cam which I use for skype (+ internal mic) were not on the available hardware lists even.
My startup drivers no longer loaded my on-board sound even. An entry for snd-hda-intel eventually fixed than, but still no cam-sound.
So I left it for a few days...
This morning, wanting to skype again, I looked around and found a damn blacklist file installed by OSS, in /etc/modprobe.d.
I checked and oss4-base was still installed, I had missed it somehow. So I removed it and removed it's modprobe files and that storted everything out.
Afterthought
I've been pondering a better setup for my PC. I try to play a few games like Eve and LOTRO when time allows. For that I have an ancient XP boot on a slow second HDD that I change to.
I think a much better setup will be a new fast HDD, installed with Windows (whatever is latest, 7, 8 ?). Then install ubuntu on a virtual box inside that. I'ts not like I need ubuntu for anything heavy, I just need it "in front" when I code, so I can just switch into the VB and work like that.
This way I wont have to reboot (well other that for windows' own moronic reasons, which I'm told is few and far between lately), and my work "machine" can be transferred if ever I upgrade windows (as opposed to the nervous "did I just fuck up my partition table" moments otherwise)
*I believe this is a Samuel Jackson line form a movie. I don't really care, I just needed an offensive title.
Monday, November 21, 2011
Monday, September 19, 2011
QOTD "Faster! Faster!"
I recently advised our team to used single quotes instead of double quotes, unless they obviously need interpolation in the strings.
Of course, I immediately got a nice reply about about a benchmark to compare the two use cases. I did not even look it up before making the recommendation. I try not to let facts cloud my opinions.
So there is the benchmark, as extolled on StackOverflow:
So doubles on the whole are just fine to use all the time. In fact, single quotes are a tad slower in basic use. Who knew.
To quote http://blog.ntrippy.net/, "Just because my opinion has changed, does not mean the fact that I'm right has."*
*See what I did there?
Of course, I immediately got a nice reply about about a benchmark to compare the two use cases. I did not even look it up before making the recommendation. I try not to let facts cloud my opinions.
So there is the benchmark, as extolled on StackOverflow:
$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.6.2]
$ cat benchmark_quotes.rb
require 'benchmark'
n = 1000000
Benchmark.bm do |x|
x.report("assign single") { n.times do; c = 'a string'; end}
x.report("assign double") { n.times do; c = "a string"; end}
x.report("assing interp") { n.times do; c = "a string #{'b string'}"; end}
x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
x.report("concat double") { n.times do; "a string " + "b string"; end}
end
$ ruby -w benchmark_quotes.rb
user system total real
assign single 2.600000 1.060000 3.660000 ( 3.720909)
assign double 2.590000 1.050000 3.640000 ( 3.675082)
assing interp 2.620000 1.050000 3.670000 ( 3.704218)
concat single 3.760000 1.080000 4.840000 ( 4.888394)
concat double 3.700000 1.070000 4.770000 ( 4.818794)
So doubles on the whole are just fine to use all the time. In fact, single quotes are a tad slower in basic use. Who knew.
To quote http://blog.ntrippy.net/, "Just because my opinion has changed, does not mean the fact that I'm right has."*
Friday, September 16, 2011
On the other other hand
I like using polymorphic tables in Rails, it's often a very nice way of structuring access to a single object from multiple points.
To define a polymorphic association, you need to to this in your class:
and on the other side
Your migration looks like:
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
# attributes ...
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
# attributes ...
To define a polymorphic association, you need to to this in your class:
class Thing < ActiveRecord::Base
belongs_to :thingable, :polymorphic => true
#...
end
and on the other side
class Foo < ActiveRecord::Base
has_may :things :as => :thingable
end
class Bar < ActiveRecord::Base
has_may :things :as => :thingable
end
Your migration looks like:
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
# attributes ...
t.string :thingable_type
#turns into thingable_id
t.belongs_to :thingable
t.timestamps
end
end
end
t.belongs_to :thingable
t.timestamps
end
end
end
Enter the hand that is short
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
# attributes ...
t.references :thingable, :polymorphic => true
t.timestamps
end
end
end
t.timestamps
end
end
end
Tuesday, September 13, 2011
Preach it sister!
I don't often/ever repost other bloggers, but this guy has such an elegant solution to serious pain in the ass, I thought I'd give him a mention.
alfajango
The problem he solves is very simply: ajax file uploads with jQuery in rails.
He explains the problem and wrote a neat gem called remotipart that just rocks, and is completely unobtrusive to the application.
Good on ya mate!
alfajango
The problem he solves is very simply: ajax file uploads with jQuery in rails.
He explains the problem and wrote a neat gem called remotipart that just rocks, and is completely unobtrusive to the application.
Good on ya mate!
Friday, September 2, 2011
The nest of despair
I've recently had the need to add a supplemental model to a user when they sign up, based on the signup info they provide.
For instance, if a user signs up the have to at least provide
However I also wanted to be able to register corporate users, so they can optionally supply
company url
Enter accepts_pain, I mean accepts_nested_attributes_for.
This is in principle a very good idea and should make implementing this sooo easy.
So, here is my model before I add it in:
and here is the model after...
At this point I should point out that you have to put accepts_asshattery after the association is defined. So in this case, after has_one :company
Ok now on to the views, and here is where the pain started.
A normal view from devise might look like this:
<%= f.label :email %>
To get nested magic, you have to add the nested fields...
<%= f.fields_for :company do |builder| %>
<%= builder.label :name %>
<%= builder.text_field :name %>
<%= builder.label :url %>
<%= builder.url_field :url %>
<% end %>
<%= f.label :email %>
<%= f.email_field :email %>
...
This however, had me running around in circles for a good long while, so I'll cut to the chase to you: The nested form requires you to specify "company_attributes" not just ":company"
The error is not, I dare say, very apparent. In my case the User model was firing off several after_create handlers, and they were all fine. Just company never created. no failure, just not call at all.
The API docs were not much help, and pointed my in the intuitive but wrong direction:
For instance, if a user signs up the have to at least provide
email
password
password confirmation
However I also wanted to be able to register corporate users, so they can optionally supply
company name
and company url
Enter accepts_pain, I mean accepts_nested_attributes_for.
This is in principle a very good idea and should make implementing this sooo easy.
So, here is my model before I add it in:
class User < ActiveRecord::Base
has_one :company
devise :registerable #keeping it simple here
validates :email, :presence => true
attr_accesible :email, :password, :password_confirmation
end
and here is the model after...
class User < ActiveRecord::Base
has_one :company
devise :registerable #keeping it simple here
validates :email, :presence => true
attr_accessible :email, :password, :password_confirmation, :company_attributes
accepts_nested_attributes_for :company
endAt this point I should point out that you have to put accepts_asshattery after the association is defined. So in this case, after has_one :company
Ok now on to the views, and here is where the pain started.
A normal view from devise might look like this:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= devise_error_messages! %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Sign up" %>
<% end %>To get nested magic, you have to add the nested fields...
...
<%= devise_error_messages! %><%= f.fields_for :company do |builder| %>
<%= builder.label :name %>
<%= builder.text_field :name %>
<%= builder.label :url %>
<%= builder.url_field :url %>
<% end %>
<%= f.label :email %>
<%= f.email_field :email %>
...
This however, had me running around in circles for a good long while, so I'll cut to the chase to you: The nested form requires you to specify "company_attributes" not just ":company"
The error is not, I dare say, very apparent. In my case the User model was firing off several after_create handlers, and they were all fine. Just company never created. no failure, just not call at all.
The API docs were not much help, and pointed my in the intuitive but wrong direction:
This model can now be used with a nested fields_for, like so:So there.
<%= form_for @person do |person_form| %> ... <%= person_form.fields_for :address do |address_fields| %> Street : <%= address_fields.text_field :street %> Zip code: <%= address_fields.text_field :zip_code %> <% end %> ... <% end %>
Monday, August 22, 2011
RSpec, Capybara and your mom
The Shirking
I've always found an excuse to do very minimal or no testing in the rails apps I write. Mostly (so I tell myself) it's because I write them all by my lonesome, so it's faster to just write it than to test it, and I trust my own code (who doesn't).
Recently though, the development team at Shuntyard has been growing and I find myself in need of some peace of mind when it comes to the code base.
The devs are good, or they would not be working with us in the first place. No, the tests are not so much for testing broken code as it is for testing broken functionality. You see, developers like to solve problems in different ways. Often simply on principle. So, when someone "cleverly" refactors a perfectly fine piece of code, we need to know if it breaks something down the line.
Enter RSpec.
I an not too concerned with unit tests or testing controllers. I trust these work well enough to get the job done, if the job gets done. So what I want to test is application behaviour. Can I log in ? Can I change my profile? Do I see a list of things when I click on the right links ? So, what I'm realy after is acceptance testing.
Enter Capybara.
There are quite a few tools out there to use for testing Rails apps. They al have merit (I presume) or they would not exist. For the testing of Wami though, I opted for something that cut close to the core, and did not abstract the testing too much.
I also make use of factory_girl_rails to construct models, instead of the default fixtures.
In a land before time...
So, on to the testing. I decided to start from scratch, so that I can see exactly how it all fit together .
First off, I added the gems for rspec, capybara to my Gemfile. I already had guard in there, having started this quest for fire on railscasts.com, guard seemed like a good tool. So here is the relevant part of my gemfile:
gem 'rspec-rails', :group => [:test, :development]
group :test do
# Pretty printed test output
gem 'turn', :require => false
gem 'capybara'
gem 'factory_girl_rails'
gem 'guard-rspec'
end
identical .rspec
exist spec
create spec/spec_helper.rb
Now, to test that a user can sign up to my site. We use devise for authentication, but that is irrelevant to the test, as I'm testing behaviour only.
To do this, I need to create a spec for signing in.
$ rails g integration_test signup
invoke rspec
create spec/requests/signups_spec.rb
For instance, I added a cellnumber to my model, even before I first ran guard.
Failure/Error: user = Factory(:user)
ActiveRecord::UnknownAttributeError:
unknown attribute: cellnumber
# ./app/models/user.rb:31:in `new'
# ./app/models/user.rb:31:in `create_primary_cell'
# ./spec/requests/sign_ins_spec.rb:5:in `block (2 levels) in'
At some point I had apparently migrated my test database, but before I added this field with a migration.
I eventually figured that the migrations was the problem, when I manually ran a
and saw the migrations run explicitly there. Starting guard up after that got through most of the tests, at least past the stumbling block.
So, remember to migrate your test DB also!
The ugly...
... part about RSpec is the counter intuitive DSL. I suppose it's hard to get it right, and there is a good deal of helpers around, but I'm yet to see a concise list of valid rspec matchers...
I'll deal with them in separate posts as I discover them.
In the meantime, where are my two tests:
I've always found an excuse to do very minimal or no testing in the rails apps I write. Mostly (so I tell myself) it's because I write them all by my lonesome, so it's faster to just write it than to test it, and I trust my own code (who doesn't).
Recently though, the development team at Shuntyard has been growing and I find myself in need of some peace of mind when it comes to the code base.
The devs are good, or they would not be working with us in the first place. No, the tests are not so much for testing broken code as it is for testing broken functionality. You see, developers like to solve problems in different ways. Often simply on principle. So, when someone "cleverly" refactors a perfectly fine piece of code, we need to know if it breaks something down the line.
Enter RSpec.
I an not too concerned with unit tests or testing controllers. I trust these work well enough to get the job done, if the job gets done. So what I want to test is application behaviour. Can I log in ? Can I change my profile? Do I see a list of things when I click on the right links ? So, what I'm realy after is acceptance testing.
Enter Capybara.
There are quite a few tools out there to use for testing Rails apps. They al have merit (I presume) or they would not exist. For the testing of Wami though, I opted for something that cut close to the core, and did not abstract the testing too much.
I also make use of factory_girl_rails to construct models, instead of the default fixtures.
In a land before time...
So, on to the testing. I decided to start from scratch, so that I can see exactly how it all fit together .
First off, I added the gems for rspec, capybara to my Gemfile. I already had guard in there, having started this quest for fire on railscasts.com, guard seemed like a good tool. So here is the relevant part of my gemfile:
gem 'rspec-rails', :group => [:test, :development]
group :test do
# Pretty printed test output
gem 'turn', :require => false
gem 'capybara'
gem 'factory_girl_rails'
gem 'guard-rspec'
end
The next step is to install rspec properly into the app:
$ rails g rspec:installidentical .rspec
exist spec
create spec/spec_helper.rb
Don't forget to wire capybara in, by adding this to your spec_helper:
require 'capybara/rails'Now, to test that a user can sign up to my site. We use devise for authentication, but that is irrelevant to the test, as I'm testing behaviour only.
To do this, I need to create a spec for signing in.
$ rails g integration_test signup
invoke rspec
create spec/requests/signups_spec.rb
Automatic, sort of
Ok, here is where the headaches started. Guard, for all it's automated goodness, was not running my migrations when I added fields to models. The errors it gives as a result are also not too untuitive.For instance, I added a cellnumber to my model, even before I first ran guard.
Failure/Error: user = Factory(:user)
ActiveRecord::UnknownAttributeError:
unknown attribute: cellnumber
# ./app/models/user.rb:31:in `new'
# ./app/models/user.rb:31:in `create_primary_cell'
# ./spec/requests/sign_ins_spec.rb:5:in `block (2 levels) in
At some point I had apparently migrated my test database, but before I added this field with a migration.
I eventually figured that the migrations was the problem, when I manually ran a
$ rake spec:requests
and saw the migrations run explicitly there. Starting guard up after that got through most of the tests, at least past the stumbling block.
So, remember to migrate your test DB also!
The ugly...
... part about RSpec is the counter intuitive DSL. I suppose it's hard to get it right, and there is a good deal of helpers around, but I'm yet to see a concise list of valid rspec matchers...
I'll deal with them in separate posts as I discover them.
In the meantime, where are my two tests:
describe "SignIns" do
it "signs in a valid user" do
user = Factory(:user)
user.confirm!
user.confirmed_at.should be_within(1.minute).of(Time.now)
visit user_session_path
fill_in "user_email" , :with => user.email
fill_in "user_password" , :with => 'secret'
click_button "Sign in"
current_path.should eq(root_path)
page.should have_content("Signed in as #{user.email}")
end
end
it "signs in a valid user" do
user = Factory(:user)
user.confirm!
user.confirmed_at.should be_within(1.minute).of(Time.now)
visit user_session_path
fill_in "user_email" , :with => user.email
fill_in "user_password" , :with => 'secret'
click_button "Sign in"
current_path.should eq(root_path)
page.should have_content("Signed in as #{user.email}")
end
end
describe "PasswordResets" do
it "emails users when requesting password reset" do
user = Factory(:user)
visit user_session_path
click_link 'password'
fill_in "Email" , :with => user.email
click_button "reset password"
current_path.should eq(user_session_path)
page.should have_content("You will receive an email with instructions about how to reset your password in a few minutes")
last_email.to.should include(user.email)
end
end
it "emails users when requesting password reset" do
user = Factory(:user)
visit user_session_path
click_link 'password'
fill_in "Email" , :with => user.email
click_button "reset password"
current_path.should eq(user_session_path)
page.should have_content("You will receive an email with instructions about how to reset your password in a few minutes")
last_email.to.should include(user.email)
end
end
Wednesday, March 2, 2011
RubySA: 3-2-offblast!
Good ideas are a good idea
It was pure happenstance that I met Angus Miller. I was not even going to check my email that evening, but the SABCs program lineup compelled me. Angus was looking for some help on a rails development project, and I had some free time on my hands. That was Wednesday 16th February.By Saturday that week we had met in person. Angus' pet dog-bear nearly ate me, but it seemed more Yogi and less, well not-Yogi*.
Very soon after first starting work together, we realised that there was significant opportunity for collaboration. Saturday's meeting was all about that. The meeting went very well, and the rest they say is history.
Backtrack a bit
In 2009 I came up with an idea for a rails-specific market management application. It would allow allow people to meet, delegate and manage collaboration on rails projects. The project saw a prototype under the working name of "Bright Market", but nothing ever came of it. I got busy with paying projects, it gathered dust. But the seeds were planted.Sidetrack
Angus has been sitting on an idea for a ruby/rails job portal. Inspired by the success of a sites like jobs.rubynow and workingwithrails, Angus felt there was a need for a local, homegrown ruby and rails jobs portal. Angus even had the foresight to register a domain, in the hopes of one day getting around to creating this app.Back to the future
We meet, we talk, RubySA is born! The production version will be switched on on Monday, March 7th.Ruby and Rails in SA
I think that Ruby and Rails are fantastic tools. In the words of Albert Schweitzer: I fancy it.And I'm not alone. The ruby and (by reasonable extension) rails communities are growing at a steady pace. This is not a fad, it's not a flavour of the month. It's a good tool, and people are realising it and using it.
With RubySA we hope to give the the local Ruby crows in South Africa, a place to call home. For now it's a job portal, cause ruby developers have got to eat, what it will be tomorrow, is up to the crowd.
* pedobear? Nothing happened swear! It was just a lick.
Subscribe to:
Posts (Atom)