Joe Van Dyk
2007-May-22 07:38 UTC
[rspec-users] Comments wanted about spec''ing out a couple controller methods
(oops, accidentally sent this to the rspec-devel list, sorry about that) Could someone help me spec out these Rails controller methods? I don''t know where to get started, especially with the transaction stuff. Or, if anyone else could suggest ways I could improve the code, that would be great as well. Puzzle has_one Media. Both are AR model objects. class PuzzlesController < ApplicationController # a before_filter fills in @user def create @puzzle = Puzzle.new(params[:puzzle]) @puzzle.user = @user @media = Media.new(:uploaded_data => params[:media]) Puzzle.transaction do @puzzle.media = @media @puzzle.save! && @media.save! flash[:notice] = "Success!" redirect_to puzzle_path(@puzzle) end rescue ActiveRecord::RecordInvalid => e @media.valid? # force checking of errors even if @puzzle.save! failed flash[:error] = "Problem submitting the One Word Wonder..." render :partial => ''new'', :layout => true end def update @puzzle = Puzzle.find params[:id] Puzzle.transaction do @puzzle.attributes = params[:puzzle] if params[:media] and params[:media].size > 0 @puzzle.media = Media.new :uploaded_data => params[:media] end @puzzle.save! && @puzzle.media.save! end rescue ActiveRecord::RecordInvalid => e @media.valid? flash[:error] = "Problem updating the One Word Wonder..." render :action => ''edit'' end Thanks, Joe Van Dyk
aslak hellesoy
2007-May-22 11:43 UTC
[rspec-users] Comments wanted about spec''ing out a couple controller methods
On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote:> (oops, accidentally sent this to the rspec-devel list, sorry about that) > > Could someone help me spec out these Rails controller methods? I > don''t know where to get started, especially with the transaction > stuff. Or, if anyone else could suggest ways I could improve the > code, that would be great as well. >This is a very busy controller. I recommend you move as much logic as possible down to the model. Along the lines of http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model I am almost 100% sure that you wrote this controller before you wrote the spec - or that you don''t have a spec. And that''s how your controller got so fat ;-) I really recommend writing the spec first - starting with an empty controller (or freshly generated one). Then let the failing tests guide you in what you have to do in the controller - not the other way around. Aslak> Puzzle has_one Media. Both are AR model objects. > > class PuzzlesController < ApplicationController > > # a before_filter fills in @user > > def create > @puzzle = Puzzle.new(params[:puzzle]) > @puzzle.user = @user > > @media = Media.new(:uploaded_data => params[:media]) > > Puzzle.transaction do > @puzzle.media = @media > @puzzle.save! && @media.save! > flash[:notice] = "Success!" > redirect_to puzzle_path(@puzzle) > end > rescue ActiveRecord::RecordInvalid => e > @media.valid? # force checking of errors even if @puzzle.save! > failed > flash[:error] = "Problem submitting the One Word Wonder..." > render :partial => ''new'', :layout => true > end > > def update > @puzzle = Puzzle.find params[:id] > Puzzle.transaction do > @puzzle.attributes = params[:puzzle] > if params[:media] and params[:media].size > 0 > @puzzle.media = Media.new :uploaded_data => params[:media] > end > @puzzle.save! && @puzzle.media.save! > end > rescue ActiveRecord::RecordInvalid => e > @media.valid? > flash[:error] = "Problem updating the One Word Wonder..." > render :action => ''edit'' > end > > Thanks, > Joe Van Dyk > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Joe Van Dyk
2007-May-22 17:06 UTC
[rspec-users] Comments wanted about spec''ing out a couple controller methods
On 5/22/07, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote: > > (oops, accidentally sent this to the rspec-devel list, sorry about that) > > > > Could someone help me spec out these Rails controller methods? I > > don''t know where to get started, especially with the transaction > > stuff. Or, if anyone else could suggest ways I could improve the > > code, that would be great as well. > > > > This is a very busy controller. I recommend you move as much logic as > possible down to the model. Along the lines of > http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model > > I am almost 100% sure that you wrote this controller before you wrote > the spec - or that you don''t have a spec. And that''s how your > controller got so fat ;-) > > I really recommend writing the spec first - starting with an empty > controller (or freshly generated one). Then let the failing tests > guide you in what you have to do in the controller - not the other way > around. > > AslakThat''s obvious. :-) I just started with rspec after the railsconf. There''s normal rails tests for these methods, but I''m trying to move towards more mocks. So, in this example, maybe I''d want to do something like this? def create @puzzle = Puzzle.new @puzzle.populate_and_save_with_user_and_puzzle_and_media_attributes @user, params[:puzzle], params[:media] if @puzzle.new_record # error stuff else # success stuff end end And then in Puzzle#populate_and_save_with_user_and_puzzle_and_media_attributes (once i find a better name) would have the transaction stuff in there?> > Puzzle has_one Media. Both are AR model objects. > > > > class PuzzlesController < ApplicationController > > > > # a before_filter fills in @user > > > > def create > > @puzzle = Puzzle.new(params[:puzzle]) > > @puzzle.user = @user > > > > @media = Media.new(:uploaded_data => params[:media]) > > > > Puzzle.transaction do > > @puzzle.media = @media > > @puzzle.save! && @media.save! > > flash[:notice] = "Success!" > > redirect_to puzzle_path(@puzzle) > > end > > rescue ActiveRecord::RecordInvalid => e > > @media.valid? # force checking of errors even if @puzzle.save! > > failed > > flash[:error] = "Problem submitting the One Word Wonder..." > > render :partial => ''new'', :layout => true > > end > > > > def update > > @puzzle = Puzzle.find params[:id] > > Puzzle.transaction do > > @puzzle.attributes = params[:puzzle] > > if params[:media] and params[:media].size > 0 > > @puzzle.media = Media.new :uploaded_data => params[:media] > > end > > @puzzle.save! && @puzzle.media.save! > > end > > rescue ActiveRecord::RecordInvalid => e > > @media.valid? > > flash[:error] = "Problem updating the One Word Wonder..." > > render :action => ''edit'' > > end > > > > Thanks, > > Joe Van Dyk > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
aslak hellesoy
2007-May-23 08:29 UTC
[rspec-users] Comments wanted about spec''ing out a couple controller methods
On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote:> On 5/22/07, aslak hellesoy <aslak.hellesoy at gmail.com> wrote: > > On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote: > > > (oops, accidentally sent this to the rspec-devel list, sorry about that) > > > > > > Could someone help me spec out these Rails controller methods? I > > > don''t know where to get started, especially with the transaction > > > stuff. Or, if anyone else could suggest ways I could improve the > > > code, that would be great as well. > > > > > > > This is a very busy controller. I recommend you move as much logic as > > possible down to the model. Along the lines of > > http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model > > > > I am almost 100% sure that you wrote this controller before you wrote > > the spec - or that you don''t have a spec. And that''s how your > > controller got so fat ;-) > > > > I really recommend writing the spec first - starting with an empty > > controller (or freshly generated one). Then let the failing tests > > guide you in what you have to do in the controller - not the other way > > around. > > > > Aslak > > That''s obvious. :-) I just started with rspec after the railsconf. > There''s normal rails tests for these methods, but I''m trying to move > towards more mocks. > > So, in this example, maybe I''d want to do something like this? > > def create > @puzzle = Puzzle.new > @puzzle.populate_and_save_with_user_and_puzzle_and_media_attributes > @user, params[:puzzle], params[:media] > if @puzzle.new_record > # error stuff > else > # success stuff > end > end > > And then in Puzzle#populate_and_save_with_user_and_puzzle_and_media_attributes > (once i find a better name) would have the transaction stuff in there? >Yes, that looks much, much better. More decoupled, more testable. When writing your specs for the controller you can now just mock the calls to #populate_and_save_with_user_and_puzzle_and_media_attributes and #new_record? so you can focus on how the controller behaves. Then I''d still recommend that the model specs go against a real database. Here you can use fixtures, or you can do like me - create all the associated objects in the example for more clarity. Cheers, Aslak> > > Puzzle has_one Media. Both are AR model objects. > > > > > > class PuzzlesController < ApplicationController > > > > > > # a before_filter fills in @user > > > > > > def create > > > @puzzle = Puzzle.new(params[:puzzle]) > > > @puzzle.user = @user > > > > > > @media = Media.new(:uploaded_data => params[:media]) > > > > > > Puzzle.transaction do > > > @puzzle.media = @media > > > @puzzle.save! && @media.save! > > > flash[:notice] = "Success!" > > > redirect_to puzzle_path(@puzzle) > > > end > > > rescue ActiveRecord::RecordInvalid => e > > > @media.valid? # force checking of errors even if @puzzle.save! > > > failed > > > flash[:error] = "Problem submitting the One Word Wonder..." > > > render :partial => ''new'', :layout => true > > > end > > > > > > def update > > > @puzzle = Puzzle.find params[:id] > > > Puzzle.transaction do > > > @puzzle.attributes = params[:puzzle] > > > if params[:media] and params[:media].size > 0 > > > @puzzle.media = Media.new :uploaded_data => params[:media] > > > end > > > @puzzle.save! && @puzzle.media.save! > > > end > > > rescue ActiveRecord::RecordInvalid => e > > > @media.valid? > > > flash[:error] = "Problem updating the One Word Wonder..." > > > render :action => ''edit'' > > > end > > > > > > Thanks, > > > Joe Van Dyk > > > _______________________________________________ > > > rspec-users mailing list > > > rspec-users at rubyforge.org > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >