RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Hey I've been using this technique for rspec to check authentication, it uses fixtures so I'm not sure if it is best practice but its pretty easy to set up.

http://pastie.caboo.se/98834

Please let me know if there is a better or easier way.

I've wondered how other people deal with this.

Cheers,

Josh

Edit: moved code into pastie --Ryan

Avatar

@QuBiT, usually I just stub out the "current_user" method in the controller to return a user of my choice. That way I can "login" any user I want.

Avatar

What about to do when you're are using an authentication tool in your program, how to you tell your tests/specs that the should log in (authenticated)first?

commenting the line with the filter when running the tests in the application controller will not be the best solution, so ...? any good ideas?

thx in advance.

Avatar

Or alternatively (in Rails > 1.2.3), simply go with Rails' flow and use "sessions" as the controller name:

script/generate authenticated user sessions

:-)

I wonder if they'll change the singular resource name convention again next time?

Avatar

@Matt, thanks for the link. That seems like a good solution in the model tests where I need some initial data to test upon. However, in the controller layer I'm sidestepping the problems with fixtures.

What I'm doing is making the tests independent of the data inside the fixtures. The only reason I'm loading them is to get loops and such in the view to execute so it finds any errors in the code. The controller tests don't care what it contains.

As mentioned in the screencast, the only thing I depend upon in the fixtures is that:
1. there's a record with the ID of 1 so I can reference it if need be
2. the data inside the fixtures is valid (so it doesn't raise any nil object errors)

If I need to test anything that depends on the content of the fixtures I'll move this to a model test and use something like what you linked to instead of fixtures.

Avatar

Hey Ryan;

Check out Lachie Cox's Hornsby Scenarios.

http://blog.allen.com.au/2007/9/17/33-702635-151-099434-hornsby

and

http://blog.smartbomb.com.au/2007/8/29/hornsby

It's awesome for getting rid of fixtures.

Avatar

@pimpmaster, I normally use growl, but I just don't for the screencast because it is distracting.

Avatar

This will work mate

namespace :migrate do
  desc "Migrates development and test databases"
  task :dev do
    puts "Migrating development database"
    Rake::Task["db:migrate"].invoke
    
    puts "Migrating test database"
    Rake::Task["db:test:clone"].invoke
    puts "Test migration complete"
  end
end

You just then call it like so

rake migrate:dev

Avatar

Instead of

post 'create'
assigns[:menu_item].should be_new_record

you can also do:

lambda { post 'create' }.should change { MenuItem.count }.by(1)

and similarly

lambda { post 'create' }.should_not change { MenuItem.count }

Avatar

Nice one Ryan :)

One thing I found surprising is that you don't use Growl notifications for your autotesting. I certainly cannot live without my red and green smileys.

Avatar

@Inimene, the reason I prefer to stub out the validation is to remove a dependency on the model. I don't want the controller test to break when I change the model validation.

Avatar

I like to test almost same way. I don't even use stub at that place. I find, that using params is better. For example I don't need to test if params get to the model. If not, then there can't be save and test fails.

Avatar

Great Episode Ryan, glad to get my Railscasts fix :)

Avatar

Ryan, that was incredibly useful, thanks. I never would have thought of it, but it makes perfect sense upon seeing it. You don't sound nearly as tired as I felt!

Avatar

Great site. This could probably have the refactoring tag added t it.

Avatar

You can place it in environment.rb, but it will then be shared across all environments. Likely you want to customize how the mailing is going to happen between environments so I recommend placing it in production.rb.

Avatar

Thanks for your source code, it saved me a lot of time! Well, if I want to use the code snippet in production, I only have to copy the code into the production.rb or is the environment.rb a better place?

Avatar

to bbb:
其他人是看不懂中国话,不过还有你这个sb可以看得懂啊。

Avatar

@Johan, try something like this:

http://pastie.caboo.se/96864

That is really ugly in the view, so what I'd probably do is move this into a helper + partial.

Avatar

@KL, yeah, just noticed this myself recently. If you are using the singular name then you will need to specify it in the routes (in edge rails).

map.resource :session, :controller => 'session'

Avatar

In my case (edge rails and latest plugin) I think it should be "sessions" controller not "session" as this matches the routing.

Avatar

Great podcasts!

How would you solve the problem if we wanted to group by year also. Like:

2006
Jan
Dec
2010
Jan
Feb

Where should i put the group_by year

Avatar

You can try calling capture near the beginning (before markaby) and setting it in a local variable. This might work better but I don't know. I recommend moving this to railsforum.com where it's easier to post code snippets and details. You can then link to it from here for those following along.

Avatar

Sorry to fill up your comments like this, if you would like me to move this to the ruby-forum or email I can do so, but I figured this will likely be good reference material for others if we can work it out. I feel like we are very close.

Messing around with concat and capture I am able to get it to output both the block and the helper html. However, the block appears before the helper, not within it. I am wondering if there is a way to concat/capture the block in a variable then feed it to the markaby block w/in the helper? Here is what I've got now:

def new_box(&block)
    b = markaby do
      div.default.box do
        h2 "Testing Markaby Helper"
        p "testing"
        capture(&block)
      end
    end
    concat b.to_s, block.binding
  end

Once again, thank you for your time!

Avatar

Have any thoughts about how (and more importantly, when) to use method_missing in any of your upcoming screencasts? I guess maybe just a little metaprogramming in general might be nice, since that's an important thing to understand in Ruby. Just a thought...

Avatar

Blocks are handled strangely in views. You'll need to use a combination of concat and capture. See this episode for details:

http://railscasts.com/episodes/40

However, considering that it's in a block already I don't know if it will work.

Avatar

That's exactly what I needed, thanks!

Stumbled across another issue that I am having trouble with though. I want to pass a block to the helper method, like so (very simplified example):

<% content_box do %>
  <p>does content for layout work?</p>
<% end %>

With the helper looking something like:

def content_box(&block)
 markaby do
   div.class do
     yield
   end
 end
end

However when I do it like that only the yield shows up and none of the markaby template. I have read that yield does not work with markaby, and to use content_for but I'm not sure how to implement it.

Thanks once again for your patience on this! If I can get this working it will improve my productivity quite a bit.

Avatar

@supaspoida, if you want to pass a parameter as a class or id, then it's probably best to use the hash instead of the method call, like this:

div :id => foo, :class => bar

And then you're just passing a string so it can be anything you want.

Regarding attaching multiple classes, you can also do this:

div.item.row

That will make two classes (item and row) I believe.

Avatar

One other question. I am trying to use this to create a content box helper method, and want to pass the id and class as options to the helper method. Is there any way to only add these variables if they exist? And can you attach multiple classes? Thanks again!

Avatar

Thanks for the prompt response! We are going to give it a try here and see how it goes. Once again your screencasts have helped tremendously, keep up the good work!

Avatar

@Lucky, yes, I would put the handling of the search wild cards into the model. That's logic that doesn't belong in the controller.

Avatar

@supaspoida, fragment caching should work fine with this technique as long as you put the "cache" block outside of the method call. This way caching is still handled on the ERB side of things. Where it becomes a problem is when you're using Markaby for a complete ERB replacement. I'm not sure if HAML has the same issues or not.

Avatar

I am very interested in using this technique, but started reading up on markaby and it seems that fragment caching is broken. Is this still the case? There is a ticket on the markaby site that says someone discovered a solution, but is it committed to the plugin yet? Does HAML suffer from this same issue?

Avatar

please teach also how to look the methods that belong to a class.
for example how to know that ActiveRecord::Base has methods named belongs_to, has_many, etc ... (since the API was on it child, but it doesnt mentioned very clear in ActiveRecord::Base).

For me Javadoc is the best API Doc because it list the parents method as well ... well. the RAILS / Ruby API doesnt list it all ..

Avatar

Great Job Ryan,
One little recommendation; If you could show how to do tests with this plugin that could help some people out. I've been trying to do TDD but having a hard time learning everything at once.
(Mainly referring to before_filter :login_required and how to create a login during a test on a controller)

Keep up the great work!

Andrew

Avatar

Hi Ryan,

One thing I noticed was that when

/page/1;edit
/page/edit/1

Avatar

@Ekolguy, I would but the by_date method is such an ugly hack that I don't want to show it. Maybe I'll improve it and turn it into an episode some day.

Regarding the routing, The name of the action shows up in the URL so there's no conflict. If I were using restful routes where the article ID showed up where the year goes, then I would have a problem. In that case I'd probably make a new route for the show action to include the date in that too.

@Ted, LOL. Actually I whipped this up right after the event last night. That's why I sound tired.

@nicolash, good idea! I'll add that. Thanks for the suggestion!

Avatar

Thanks for your screencasts.

Maybe you should consider a Tag "routing" for these editions...

070_custom_routes
046_catch_all_route
035_custom_rest_actions
034_named_routes

Avatar

I'm telling Jack you were working on a new episode while he was slaving over your Rails Rumble project ;-)

Avatar

@ekolguy

I guess it shouldnt matter because what the route is aiming to do is to stop the show action being interpreted as a date (for the index action)

Avatar

Thanks for this one Ryan!

It would be nice to see the code for by_date method too though.

Also what happens if the id of the article has 4 characters in it? Any other method of escaping from this?

Cheers.

Avatar

Thank you so much for this and rest of the Railscasts. This saved my butt today!

Avatar

Hi Ryan,

On this topic "Move Find into Model", I have queries which I hope you could help to enlighten me:

I provide CRUD of books. First, user will have to select the action (i.e. C, R, U or D) from the menu. Then, a search screen is displayed for user to enter the book title/s which s/he would like to check.

The search string could contain more than one word, * (0 or more character wild card), ? (single character wild card) and so on.

In this case, should the formatting and validation of the search string be also embedded in the Book model, together with the Find in the Book model? If not, where should this be included?

Thank you for your help.

Avatar

Hi Ryan,

I have been checking your website for more has_many :through articles.

I have this question which I hope you could provide your insights, as I have been checking around but to-date still could not fully understand.

I would greatly appreciate if you could look at my code on http://railsforum.com/viewtopic.php?id=10204

I have these 2 tables: groups and users, where a group can have many users and an user can have many groups.

I have this third table, roles, which contains group_id, user_id, type. The field 'type' can be Administrator, Owner and Member. A user can play the role of Owner for a group but assume the role of member for another group. I use this table as Single Table Inheritance.

I want to do such query:
Based on a given user's id, I want to
display all the groups of this user, with the respective role for that group.

I have been reading and trying the associations. The last working association I tried is (assuming the user-id I want to check is 1):

User.find(1).roles.each do |role|
  <%= role.group.name %>
end

Is that the way to perform such query?

Thank you, for your great effort in sharing your knowledge with others.

Thank you very much.

Avatar

Just thought I should add that if you want it to install with activation, just include :include_activation as an option when you install

Avatar

I just installed this and somehow didn't notice that there was an activation option. I wrote my own before figuring it out, and it ended up being the same thing anyway.

Just wanted to say that it is super easy to install with activation, and even without knowing that option was there, this screencast made my decision for me on how to authenticate.

Thanks Ryan!!!

Avatar

It seems HAML is efficient for templates, but not quite as much in helpers. The Markaby in this helper example has less noise than the HAML equivalent.

Avatar

你说中国话谁看的懂啊,sb啊
rails2。0早着呢
.. ... .
Hello,everybody!

Avatar

You can add tail to windows C:\Program Files\Windows Resource Kits\Tools.. Tail.exe . Thanks Ryan.Great Work!!!!!!!!!!!!!