RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Great episode! How can i update my crontab every time i deploy my application using the 'thin' server instead of 'capistrano' and deploy it as a rails 3.1 app to heroku?

Avatar

You're totally right / I completely overlooked the two arguments making my solution wrong.

Generally, I don't like the "class goes in, instance comes out" approach but I think it's fine in this case

Avatar

How would using HAML change the presenter implementation?

Avatar

@ryan how about using draper with gems like decent exposure. The easy way would be something like

ruby
expose(:user) { UserDecorator.find(params[:id])

how about a modified episode that show how by default to use decent exposure and Decorators.

Love the screen cast, they are my weekly dose of something awesome in the rails world.

Avatar

Hey Ryan!

It was great episode. Just one think I really didn't like was defining presents method in base presenter. It could be something optional to use but in most cases we have 1-1 relation which can be expressed in BasePresenter in following way:

ruby
  def self.inherited(klass)
    name = klass.name.match(/(\w+)Presenter/).captures.first.underscore
    define_method(name) { @object }
  end

what do you think?

Avatar

why? Any particular reason for that?
and by the way: you frget that presenter initalizer takes 2 arguments

Avatar

I added spec/support/presenters.rb file and I require it from spec_helper.rb:

ruby
RSpec.configure do |config|
  config.include ActionView::TestCase::Behavior, example_group: {file_path: %r{spec/presenters}}
  config.include RSpec::Rails::Matchers::RenderTemplate, example_group: {file_path: %r{spec/presenters}}
end

the later instruction allows me simple check if presenter renders a template inside test

ruby
presenter.method.should render_template('blah/_blah')
Avatar

Suggested refactor:

ruby
module ApplicationHelper
  def present(object, presenter = "#{object.class}Presenter".constantize.new )
    yield presenter if block_given?
    presenter
  end
end

It's better to pass an instance as a parameter than a class

rhtml
<% present @user, UserPresenter.new do %>

  <!--- stuff --> 

<% end %>

<!-- or -->

<% present @user do %>

  <!--- stuff --> 

<% end %>
Avatar

Agree, small red/green numbers in the corner of comment could simplify navigation.

Avatar

I'd +1 that

My favourite ruby book of all time is Metaprogramming Ruby

The thing I loved most about this book is that BDD is part of every example. I always feel that by showing just the code, you're only showing half of the solution to a problem?

Avatar

Anyone experienced prePopulate tags not showing up on Heroku? I can't explain why most of my tags do, but the one with id#1 doesn't

Avatar

Works great. One thing I had to do in order for "Sign Out" to work properly with Devise was to make the following change in initializers/active_admin.rb:

ruby
config.logout_link_method = :delete
Avatar

"appication.css.scss" should be "application.css.scss" in the shownotes

Avatar

instead of moving sass-rails outside the :assets group, we just need to put 'activeadmin' after that group, does it work?

Avatar

I got my errors to go away by changing the mass_assignment authorizer to look like this:

ruby
def mass_assignment_authorizer(role = :default)
    super(role) + (dynamic_accessible_attributes || [])
end

I'm not sure if it's right, though.

Avatar

I'm curious why you don't feel the controller should know about Presenters? It seems to me the one thing controllers and presenters have in common, is they both have knowledge of both the model and the view.

I need to look more into the subtle differences between presenters and decorators... maybe understanding that will help me understand why you think the presenters should be instantiated in the view.

Avatar

I have a question about pagination on large sets, on the order of 100 million.

Both will_paginate and Kaminari count the records to count the number of pages that are necessary, and since I am using Postgres counts are god-awful slow.

I've hacked around it with a smart partial that will create an infinite paginator if the query will return over 5000 records (this number was chosen because 5000 can be counted quickly, and I feel confident that people won't browse through 5000 records without narrowing their search).

Anyone have any thoughts?

Avatar

Thanks Ryan !!
The discussions in comments are also very informative, can't we just have a like options there for comments. Most of the times, it happens i don't have something to say, but just liked answers.

Avatar

Thanks Ryan for this. I had tried the gem before you release this tut and i love it straight off. I have a little problem, maybe you have the answer. How do i add a different role? like user. I have tried following the device way. rails generate devise:views users but it doesn't seem to work. Any ideas?

Avatar

@Dave Kimura:

you're right, I wrongly used erb commenting syntax into haml environment. That's for app/views/kaminari/_paginator.html.haml ...

but what about

= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote

= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote

rispectively in :
./app/views/kaminari/_prev_page.html.haml
and
./app/views/kaminari/_first_page.html.haml

How do you change them ?

Avatar
ruby
ModelName.limit(100).paginate etc...
Avatar

Thanks heaps Ryan. I've built a subdomain-based link shortener with help from your screencast.

Avatar

In case it helps anyone else, I believe the the favored way of doing this in Rails 3+ is with the method "accepts_nested_attributes_for".

http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

Avatar

There is a special pro feed you need to subscribe to.

Go to http://railscasts.com/pro , click "Manage you subscription" and then click "RSS Feed" (follow the instructions there to add the feed to iTunes)

Avatar

instead of commenting out, try to remove the

#unless current_page.first?

#unless current_page.last?

Avatar

@Dave Kimura:

... done:

= paginator.render do
%nav.pagination
= first_page_tag #unless current_page.first?
= prev_page_tag #unless current_page.first?
- each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window?
= page_tag page
- elsif !page.was_truncated?
= gap_tag
= next_page_tag #unless current_page.last?
= last_page_tag #unless current_page.last?

but it doesn't work :-(

Avatar

I had this issue as well. Move the code into a helper and you'll be good to go. Sorry if that's outdated but if anyone else google's this at least they have an answer.

Avatar

Can't see Railscasts pro in rss feed :(

Avatar

Is there any workaround for using will_paginate with active_admin?

Avatar

Thanks for great screencast. Loving the Pro service!

One question regarding pagination. Is it possible to paginate within limited set of records. Eg. If my table contains 300 records and i only want to show the first 100 records to users and then paginate only on those 100 records?

Avatar

I'm aware of the Kaminari + will_paginate breakage in scenarios like when using activeadmin and I'll try to do something about it.

The way you customized previous/next labels, Ryan, is now deprecated. You should customize text via your app's locale files

Avatar

Ryan, thank you very much for this great episode. I created a gem using your approach on presenters. Check it out: exhibit.

Avatar

Like Ryan said about decorating a User - Posts assocation, you just have to create a method UserDecorator#appointment with AppointmentDecorator.new(model.appointment).

Avatar

I've been trying to add ckeditor to the form. I have tried using the formtastic dsl but the toolbar dosen't appear.I am using rails3-ckeditor.

Avatar

you were right. found and fixed. thx!

Avatar

Looks like they have updated the :views file. If you're wanting to add the First/Previous/Next/Last in the view so that it doesn't disappear when appropriate, just remove the lines

unless current_page.first?

unless current_page.last?

in the _paginator.html.erb file

Avatar

The show notes point out that this follows the work covered in http://railscasts.com/episodes/275-how-i-test. In that episode Ryan showed us how he handles testing on a normal project. His techniques there would cover what you are talking about.

Avatar

Thanks for the great episode!

I have a question. If my user model has_one appointment model, both of which have decorators declared, is there a way to call the decorator for appointment from the user? like user.appointment.avatar ? or maybe user.appointmentDecorator.avatar ?

Avatar

A nice enhancement in version 0.3.2, you can turn your site title into a link. For instance to get out of admin mode and back to your regular site:

config.site_title_link = :root

Avatar

i would suggest to you make a new video or expand current code sample to show how test/spec the views after apply a presenter on it.
I think it is missing to be full complete episode.
Thanks for you great work!

Avatar

Put your custom css in a separate file and tell ActiveAdmin to load it: https://github.com/gregbell/active_admin/issues/261

Avatar

OK, repeated you tutorial. Just started with Rails and wanted to check out a good TDD scheme for Ruby and found Cucumber & RSpec. The homepages are nice for experts, but not a single step-by-step guide for getting it to work for newbs. Especially the rake commands are given NOWHERE and as a newb the problem with tables reported by Cucumber (if you don't know you need to clone) and the official Cucumber Wiki example actually using a table in the feature got me going crazy... Your railscast on this should become part of the official documentation! Thanks loads, man!!!
Reply

Avatar

I think the apx. length of your casts is perfect!
I didn't miss a single episode since #1 but I wouldn't have time to watch a 1h cast each Monday.

Keep going and congrats for Pro!

Avatar

Glad to see this - we've started using Draper at Tribesports recently, and we're really happy with it. We wrote a couple of blog posts on how it can help implement a clean, versioned API, if anyone's interested:

Part 1 - Versioning the Tribesports API
Part 2 - Separating API logic with decorators

We're actually using it in combination with Cells (mentioned above); we think they're highly complementary. Our site makes heavy use of small resource-specific elements repeated in multiple contexts. Cells lets us pick out the resources we're displaying in a structured manner (cleaning up our controllers), and draper handles the decoration, cleaning up the views.

Avatar

Don't think so. Those comments are great free advertising for Ryan and show both how people like the screencast and how good his support is.

Avatar

Hello Helmut,
You may want to checkout http://www.peepcode.com. I subscribe to both (RailsCasts Pro and Peepcode) and find that they nicely compliment each other. Producing full length screencasts once a week is a very difficult thing to do. That is why Peepcode averages one screencasts a month (more or less). It is very nice to have Ryan's screencasts every week :)