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...

http://guides.rubyonrails.org/testing.html

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...

http://guides.rubyonrails.org/testing.html

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