![]() |
Writing Better Railsby Craig Buchek — August 8, 2011 — St. Louis Ruby Users Group Agenda
Cucumber Stories
Scenario: Reset my password Given a user with nickname "john" and email "john@john.com" And I am on the reset password page When I fill in "Nickname" with "john" And I press "Send me reset password instructions" And "john@john.com" opens the email with subject "Reset password instructions" And I follow "sign in to glu" in the email And I fill in the following: | Password | pass1235 | | Password confirmation | pass1235 | And I press "Change my password" Then I should see "Your password was changed successfully." And I should be on my dashboard page
Scenario: suggestion from logged in user via "Stay Tuned" modal Given I am logged in When I submit feedback via the stay tuned dialog Then an email gets sent to the feedback email address And the email contains my username And the email contains my comment Cucumber Step Definitions
FEEDBACK_COMMENT = 'This is the text of my comment' When /^I submit feedback via the stay tuned dialog$/ do And %(I go to the question of the day page) And %(I follow 'submit your own question') And %(I should see a message saying stay tuned) And %(I fill in 'Comment' with "#{FEEDBACK_COMMENT}" within '.ui-dialog') And %(I press 'Submit' within '.ui-dialog') end
FEEDBACK_COMMENT = 'This is the text of my comment' When /^I submit feedback via the stay tuned dialog$/ do visit question_of_the_day_path click_link 'submit your own question' page.should have_content('stay tuned') within ".ui-dialog" do fill_in 'Comment', :with => FEEDBACK_COMMENT click_button 'Submit' end end
Cleaner Specs
describe '#read_and_unread_messages' do subject { current_user.mailbox } let(:current_user) { Factory :enrolled_user } let(:other_user) { Factory :enrolled_user } let(:message1) { Factory.build :message, :to => current_user, :from => other_user, :body => "message 1" } let(:message2) { Factory.build :message, :to => other_user, :from => current_user, :body => "message 2" } it 'includes messages sent to me' do subject.read_and_unread_messages.to_a.should include(message1) end it 'does not include messages I sent' do subject.read_and_unread_messages.to_a.should_not include(message2) end end describe Mailbox do describe "#delete_message" do context 'when the message is in the deleted folder' do it 'saves the mailbox' it 'removes the message id from the deleted folder' it 'tells the message to decrement its reference count' it 'decrements the deleted messages count' end end end describe Mailbox::Folder::MessagesController do describe "#index" do let(:messages) { mock 'messages array' } let(:params) { {:folder_id => 'deleted'} } before do subject.stub(:messages) { messages } end it 'responds with the messages' do subject.should_receive(:respond_with).with(messages) get :index, params end end end Simpler Controllers
class DeletedMessagesController < ApplicationController respond_to :html, :only => [:index, :destroy] respond_to :json expose(:messages) { current_user.mailbox.deleted_messages } expose(:message) def index respond_with messages end def destroy current_user.mailbox.delete_message(message) respond_with message, :location => deleted_messages_path end end Skinny Controller / Fat Model
What If A Model Gets Too Fat?
How To Write Models
Attempt #1 - Modules
Attempt #2 - Split Off Some Functionality
Idea #3 - Split DAO and Business Logic
Idea #4 - Composite Object
class User field :mailbox delegate :messages, :to => :mailbox Idea # 5 - DCI
Idea # 6 - Composite Command Pattern
Idea # 7 - ServicesViews
Further Ideas
References
Books |
![]() |