how does the controller "know" about the model?

I am going through the Depot application tutorial in the Agile book and have a question...

How is that I can put a reference to my model (i.e. @products = Produts.all) in my store controller (or any other for that matter) and it just "knows" about it.

To me that seems a lot like global variables which I thought were a no-no. I would expect a require statement at the top or something like that.

In Rails, all controllers know about all models. The controllers are just a way to namespace your app into separate logical pieces. When you do Product.all, Product is a class where all your model methods live, it has nothing to do with any controllers.

In Ruby, global variables begin with $.

Hi,

  I'm a Rails newbie myself, but I think that all required .rb files are automatically required when you boot up your app by invoking "script/server". This probably done in either boot.rb or environment.rb. If you didn't know, you can invoke "script/console" and create objects from your model in an irb-like command line. I believe it works the same way. Everything that's required, is automatically required by the framework's internals.

  (If I'm wrong, there is probably someone more knowledgable that could clarify further).

Thanks for the responses!

So to me it seems like Ruby/Rails controllers know about the model; since Rails "stitches" the view, controllers and model together for you I guess that makes sense.

A similar thing that is throwing me for a loop is something like this.

  test "should get index" do     get :index     assert_response :success     assert_select '#columns #side a' , :minimum => 4     assert_select '#main .entry' , 3     assert_select 'h3' , 'Programming Ruby 1.9'     assert_select '.price' , /\$[,\d]+\.\d\d/   end

This is a unit test from the book. The assert_select(s) test the html response. But, this really confuses me because I see now response anywhere? How in the world do the assert statements know of the HTML that was generated?

Thanks for the responses!

So to me it seems like Ruby/Rails controllers know about the model; since Rails "stitches" the view, controllers and model together for you I guess that makes sense.

A similar thing that is throwing me for a loop is something like this.

test "should get index" do    get :index

This 'get' statement makes a request and gets the response. All the other methods know about that response. The details are hidden away...

   assert_response :success    assert_select '#columns #side a' , :minimum => 4    assert_select '#main .entry' , 3    assert_select 'h3' , 'Programming Ruby 1.9'    assert_select '.price' , /\$[,\d]+\.\d\d/ end

This is a unit test from the book. The assert_select(s) test the html response. But, this really confuses me because I see now response anywhere? How in the world do the assert statements know of the HTML that was generated?

See here for more...

Carl Jenkins wrote:

Thanks for the responses!

So to me it seems like Ruby/Rails controllers know about the model; since Rails "stitches" the view, controllers and model together for you I guess that makes sense.

A similar thing that is throwing me for a loop is something like this.

  test "should get index" do     get :index     assert_response :success     assert_select '#columns #side a' , :minimum => 4     assert_select '#main .entry' , 3     assert_select 'h3' , 'Programming Ruby 1.9'     assert_select '.price' , /\$[,\d]+\.\d\d/   end

This is a unit test from the book. The assert_select(s) test the html response. But, this really confuses me because I see now response anywhere?

What would you expect to see that you're not seeing? Why is this confusing you?

How in the world do the assert statements know of the HTML that was generated?

Why not look at the Test::Unit source code to find out?

(BTW, I recommend switching from Test::Unit to RSpec as soon as possible.)

Best,

Philip Hallstrom wrote:

Thanks for the responses!

So to me it seems like Ruby/Rails controllers know about the model; since Rails "stitches" the view, controllers and model together for you I guess that makes sense.

A similar thing that is throwing me for a loop is something like this.

test "should get index" do    get :index

This 'get' statement makes a request and gets the response. All the other methods know about that response. The details are hidden away...

How in the world do the assert statements know of the HTML that was generated?

See here for more...

Testing Rails Applications — Ruby on Rails Guides

Ahh - thanks for the response(and link)

I recommend staying with Test::Unit. It comes with Rails and works great.

Greg Donald wrote:

(BTW, I recommend switching from Test::Unit to RSpec as soon as possible.)

I recommend staying with Test::Unit. It comes with Rails and works great.

I'm glad you like it. It is my experience, and that of a large number of other Rails developers, that using RSpec leads to more readable and maintainable tests that focus more on behavior and less on implementation. I don't see a single advantage of Test::Unit over RSpec (except for the trivial one of its being included with Rails), whereas RSpec has huge advantages over Test::Unit as I outlined above, as well as probably being more beginner-friendly.

But we're losing the topic here, so I'll stop now.

-- Greg Donald destiney.com | gregdonald.com

Best,

It is my experience, and that of a large number of other Rails developers, that using RSpec leads to more readable and maintainable tests

They both do the exact same thing. The assertion syntax is nearly identical. RSpec just requires that you type a lot more to do the same job.

that focus more on behavior and less on implementation. I don't see a single advantage of Test::Unit over RSpec (except for the trivial one of its being included with Rails),

I personally don't see the need to type all that extra RSpec syntax when I can type much simpler tests using Test::Unit. If RSpec were so great, why is it still not the default, even with Rails3?

whereas RSpec has huge advantages over Test::Unit as I outlined above, as well as probably being more beginner-friendly.

What advantages? They both do the _exact same thing_, the main difference is the syntax, one is smaller one is bigger. I'll stick with the one that requires less work.

Greg Donald wrote:

It is my experience, and that of a large number of other Rails developers, that using RSpec leads to more readable and maintainable tests

They both do the exact same thing. The assertion syntax is nearly identical. RSpec just requires that you type a lot more to do the same job.

that focus more on behavior and less on implementation. �I don't see a single advantage of Test::Unit over RSpec (except for the trivial one of its being included with Rails),

I personally don't see the need to type all that extra RSpec syntax when I can type much simpler tests using Test::Unit.

I've never been able to write or seen anyone else write Test::Unit tests that were actually readable and maintainable. RSpec's extra syntax encourages a different style of test that is readable.

If RSpec were so great, why is it still not the default, even with Rails3?

Who knows? I can't speak for the core team. My guess -- and it *is* a guess -- is that it's because the Rails core team has a bad case of Not Invented Here syndrome in some respects. This is nicely fed into by the assumptions of many Rails developers that the core team's decisions are perfect and needn't be questioned.

whereas RSpec has huge advantages over Test::Unit as I outlined above, as well as probably being more beginner-friendly.

What advantages? They both do the _exact same thing_, the main difference is the syntax, one is smaller one is bigger.

Correct. The RSpec syntax encourages a different style of writing tests.

I'll stick with the one that requires less work.

So will I. That would be RSpec. The extra typing is trivial compared to the advantage of actually having tests that don't require elaborate deciphering 6 months later.

-- Greg Donald destiney.com | gregdonald.com

Best,

Test::Unit tests like I write are very easy to decipher:

test "should have a first name" do

end

Seems easy to me.

Greg Donald wrote:

test "should have a first name" do     count = User.count( :all )     u = User.new( :email => 'foobar@example.com', :password => 'xxxxxxxx', :lname => 'foobar', :last_login => Time.now )     assert !u.valid?     assert_not_nil u.errors[:fname]     assert_equal count, User.count( :all )     u.fname = 'foo'     assert u.save     assert_equal count + 1, User.count( :all )   end

  test "user can login" do     get :login     assert_response :success     post :login, { :login => { :email => 'foo@bar.com',                                :password => 'changeme' } }     assert_redirected_to '/'     assert_not_nil session[:user_id]   end

What's so hard to read?

No, I just don't see a reason to throw away a perfectly good and working Test::Unit integration in favor of a separate Rspec for purley academic reasons. They do the same thing. The assertions do the same thing. The main difference is one requires more syntax to do the same work.

Maybe one day the Rails core team will be as smart as you and switch to Rspec, until then..

Greg Donald wrote:

...and you've conveniently left out the hard-to-read assert statements.

  test "should have a first name" do     count = User.count( :all )     u = User.new( :email => 'foobar@example.com', :password => 'xxxxxxxx', :lname => 'foobar', :last_login => Time.now )     assert !u.valid?     assert_not_nil u.errors[:fname]     assert_equal count, User.count( :all )     u.fname = 'foo'     assert u.save     assert_equal count + 1, User.count( :all )   end

  test "user can login" do     get :login     assert_response :success     post :login, { :login => { :email => 'foo@bar.com',                                :password => 'changeme' } }     assert_redirected_to '/'     assert_not_nil session[:user_id]   end

What's so hard to read?

Just about every line of that is hard to read IMHO. I find assert_equal a, b to look cryptic and require me to stop and think every time I see it. By contrast, a.should == b reads more like English (or idiomatic Ruby) and reads quickly and easily for me. (It's also less typing than the Test::Unit version.)

I'll post an RSpec version for comparison when I'm not typing on my phone. I don't know why you continue to torture yourself with assert_ syntax. :slight_smile:

-- Greg Donald destiney.com | gregdonald.com

Best,

Just about every line of that is hard to read IMHO. I find assert_equal a, b to look cryptic and require me to stop and think every time I see it. By contrast, a.should == b reads more like English (or idiomatic Ruby) and reads quickly and easily for me. (It's also less typing than the Test::Unit version.)

Sounds like a question of habit/personal preference to me - I can't say I've ever found assert_equal hard to understand.

Personally I don't really care whether I write should or assert - you can get the job done either way (although http://pragdave.blogs.pragprog.com/pragdave/2008/03/the-language-in.html is an interesting articles on DSLs trying to be too much like english) and I find the mindset of the developer to be more important that the test syntax used to express it.

Fred