My model is very simple, it''s mostly just a join table that represents which tournaments a user has registered for. class Registration < ActiveRecord::Base belongs_to :user belongs_to :tournament validates_presence_of :user_id, :tournament_id validates_uniqueness_of :user_id, :scope => :tournament_id end the validates_uniqueness checks to make sure there''s no record that has the same user_id and tournament_id. Is there a relatively easy way to specify this behavior? The only way that I know is to do something like context "A Registration with a User and Tournament" do setup do @user = User.new @user.save false @tournament = Tournament.new @tournament.save false @reg = Registration.new(:user => @user, :tournament => @tournament) end specify "should be valid" do @reg.should_be_valid end specify "should not be valid if a registration with the same details already exists" do @reg.save Registration.new(:user => @user, :tournament => @tournament).should_not_be_valid end end Well actually that''s obviously pretty easy :) Is it bad that I''m tied to the implementations of User and Tournament at all? ActiveRecord dictates that, so I guess it''s not a problem to have that in my spec at all. Anyway this is just the spec I came up with and I''m wondering if anyone else has a better idea. Pat
oh, I forgot to say that the @user.save(false) means that the user object gets saved but skips validation. That''s a quick way of not having to create a completely valid user object that may become out of date as you change the User model. and happy new year everyone! Pat
On 1/1/07, Pat Maddox <pergesu at gmail.com> wrote:> oh, I forgot to say that the @user.save(false) means that the user > object gets saved but skips validation. That''s a quick way of not > having to create a completely valid user object that may become out of > date as you change the User model.That''s the kind of stuff you should be blogging! Very useful tip. Thanks Pat.> > and happy new year everyone!You too! David> > Pat > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 1/1/07, Pat Maddox <pergesu at gmail.com> wrote:> My model is very simple, it''s mostly just a join table that represents > which tournaments a user has registered for. > > class Registration < ActiveRecord::Base > belongs_to :user > belongs_to :tournament > > validates_presence_of :user_id, :tournament_id > validates_uniqueness_of :user_id, :scope => :tournament_id > end > > the validates_uniqueness checks to make sure there''s no record that > has the same user_id and tournament_id. > > Is there a relatively easy way to specify this behavior? The only way > that I know is to do something like > > context "A Registration with a User and Tournament" do > setup do > @user = User.new > @user.save false > @tournament = Tournament.new > @tournament.save false > @reg = Registration.new(:user => @user, :tournament => @tournament) > end > > specify "should be valid" do > @reg.should_be_valid > end > > specify "should not be valid if a registration with the same details > already exists" do > @reg.save > Registration.new(:user => @user, :tournament => > @tournament).should_not_be_valid > end > endGeez, ActiveRecord models are SUCH a violation of SRP! I realize that this is the rails way, and that there are great productivity benefits we glean from AR, but having a model that validates both at both the instance level (validates_presence_of) and the class level (validates_uniqueness_of) is a pain in the ass. It''s confusing because both sorts of validations look the same, but they are really fundamentally different. Ranting aside, there are a couple of different ways you can view this. To be the most clear, I''d probably spec the class level validations separately from instance level validations. The uniqueness spec might look like this: context "The Registration model class" do setup do @user1 = User.new @user2 = User.new @tournament = Tournament.new [@user1, @user2, @tournament].each {|model| model.save(false)} end specify "should permit registrations with different users" do Registration.create(:user => @user1, :tournament => @tournament) Registration.new(:user => @user2, :tournament => @tournament).should_be_valid end specify "should deny multiple registrations with the same user" do Registration.create(:user => @user1, :tournament => @tournament) Registration.new(:user => @user1, :tournament => @tournament).should_not_be_valid end end WDYT?> > Well actually that''s obviously pretty easy :) Is it bad that I''m tied > to the implementations of User and Tournament at all? ActiveRecord > dictates that, so I guess it''s not a problem to have that in my spec > at all. > > Anyway this is just the spec I came up with and I''m wondering if > anyone else has a better idea. > > Pat > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 1/1/07, David Chelimsky <dchelimsky at gmail.com> wrote:> On 1/1/07, Pat Maddox <pergesu at gmail.com> wrote: > > My model is very simple, it''s mostly just a join table that represents > > which tournaments a user has registered for. > > > > class Registration < ActiveRecord::Base > > belongs_to :user > > belongs_to :tournament > > > > validates_presence_of :user_id, :tournament_id > > validates_uniqueness_of :user_id, :scope => :tournament_id > > end > > > > the validates_uniqueness checks to make sure there''s no record that > > has the same user_id and tournament_id. > > > > Is there a relatively easy way to specify this behavior? The only way > > that I know is to do something like > > > > context "A Registration with a User and Tournament" do > > setup do > > @user = User.new > > @user.save false > > @tournament = Tournament.new > > @tournament.save false > > @reg = Registration.new(:user => @user, :tournament => @tournament) > > end > > > > specify "should be valid" do > > @reg.should_be_valid > > end > > > > specify "should not be valid if a registration with the same details > > already exists" do > > @reg.save > > Registration.new(:user => @user, :tournament => > > @tournament).should_not_be_valid > > end > > end > > Geez, ActiveRecord models are SUCH a violation of SRP! I realize that > this is the rails way, and that there are great productivity benefits > we glean from AR, but having a model that validates both at both the > instance level (validates_presence_of) and the class level > (validates_uniqueness_of) is a pain in the ass. It''s confusing because > both sorts of validations look the same, but they are really > fundamentally different. > > Ranting aside, there are a couple of different ways you can view this. > To be the most clear, I''d probably spec the class level validations > separately from instance level validations. The uniqueness spec might > look like this: > > context "The Registration model class" do > setup do > @user1 = User.new > @user2 = User.new > @tournament = Tournament.new > > [@user1, @user2, @tournament].each {|model| model.save(false)} > end > > specify "should permit registrations with different users" do > Registration.create(:user => @user1, :tournament => @tournament) > Registration.new(:user => @user2, :tournament => > @tournament).should_be_valid > end > > specify "should deny multiple registrations with the same user" do > Registration.create(:user => @user1, :tournament => @tournament) > Registration.new(:user => @user1, :tournament => > @tournament).should_not_be_valid > end > end > > WDYT?That makes a lot of sense. I''m finding that, as productive as I am with Rails, RSpec is helping me find a lot of deficiencies in the Rails philosophy, but far more importantly in my own thinking. I''ve learned that I have to pay a LOT more attention than I have been when coding...and I consider myself a mindful programmer to begin with. I know it sounds obvious that you have to pay attention, but it can be tough in practice. Anyway I''m loving RSpec, if only because I''m asking more design questions than I was before. Whenever a spec is awkward to write or implement, it''s time to investigate further. Thanks a lot for the input. Pat
On 1/4/07, Pat Maddox <pergesu at gmail.com> wrote:> On 1/1/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > On 1/1/07, Pat Maddox <pergesu at gmail.com> wrote: > > > My model is very simple, it''s mostly just a join table that represents > > > which tournaments a user has registered for. > > > > > > class Registration < ActiveRecord::Base > > > belongs_to :user > > > belongs_to :tournament > > > > > > validates_presence_of :user_id, :tournament_id > > > validates_uniqueness_of :user_id, :scope => :tournament_id > > > end > > > > > > the validates_uniqueness checks to make sure there''s no record that > > > has the same user_id and tournament_id. > > > > > > Is there a relatively easy way to specify this behavior? The only way > > > that I know is to do something like > > > > > > context "A Registration with a User and Tournament" do > > > setup do > > > @user = User.new > > > @user.save false > > > @tournament = Tournament.new > > > @tournament.save false > > > @reg = Registration.new(:user => @user, :tournament => @tournament) > > > end > > > > > > specify "should be valid" do > > > @reg.should_be_valid > > > end > > > > > > specify "should not be valid if a registration with the same details > > > already exists" do > > > @reg.save > > > Registration.new(:user => @user, :tournament => > > > @tournament).should_not_be_valid > > > end > > > end > > > > Geez, ActiveRecord models are SUCH a violation of SRP! I realize that > > this is the rails way, and that there are great productivity benefits > > we glean from AR, but having a model that validates both at both the > > instance level (validates_presence_of) and the class level > > (validates_uniqueness_of) is a pain in the ass. It''s confusing because > > both sorts of validations look the same, but they are really > > fundamentally different. > > > > Ranting aside, there are a couple of different ways you can view this. > > To be the most clear, I''d probably spec the class level validations > > separately from instance level validations. The uniqueness spec might > > look like this: > > > > context "The Registration model class" do > > setup do > > @user1 = User.new > > @user2 = User.new > > @tournament = Tournament.new > > > > [@user1, @user2, @tournament].each {|model| model.save(false)} > > end > > > > specify "should permit registrations with different users" do > > Registration.create(:user => @user1, :tournament => @tournament) > > Registration.new(:user => @user2, :tournament => > > @tournament).should_be_valid > > end > > > > specify "should deny multiple registrations with the same user" do > > Registration.create(:user => @user1, :tournament => @tournament) > > Registration.new(:user => @user1, :tournament => > > @tournament).should_not_be_valid > > end > > end > > > > WDYT? > > That makes a lot of sense. I''m finding that, as productive as I am > with Rails, RSpec is helping me find a lot of deficiencies in the > Rails philosophy, but far more importantly in my own thinking. > > I''ve learned that I have to pay a LOT more attention than I have been > when coding...and I consider myself a mindful programmer to begin > with. I know it sounds obvious that you have to pay attention, but it > can be tough in practice.It''s REALLY tough in practice. But that''s what separates the geniuses from the rest of us. In programming and in any other craft. I was just discussing this with a jazz singer in my family - how there are some people who just live in the zone. The rest of us can only aspire to that by continuing to practice and pay attention when we do. Hopefully, eventually, you don''t have to pay attention and good stuff just happens as a matter of course.> Anyway I''m loving RSpec, if only because I''m asking more design > questions than I was before. Whenever a spec is awkward to write or > implement, it''s time to investigate further.Can I quote you on that?> > Thanks a lot for the input. > > Pat > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >