Ryan,
I am so pleased that you have decided to offer more screencasts. Thanks for all your great work, you have passed on an incredible amount of knowledge over the years through these screencasts.
Hi, question. I'm using rspec, and added the 'include ActionView::TestCase::Behavior' as you recommended. However, I'm getting a "undefined method 'setup'" error from action_controller/test_case.rb:12. I am using Rails 3.1.
Sounds neat, but all the examples look like a single resource. What about more complex examples; such as a User has_many Posts... In the view one might have a @user.posts.each |post| do ... how do you get a decorator object for those?
Presenter design pattern aka presenter refactoring is a way of simplifying controller logic by extracting it out into its own class which has one or more methods. Thus, making it easier to test controller logic by usually transforming each assigned instance variable in a controller action into its own method within the presenter class. Anytime you see a controller action which has many instances variables, it needs to be refactored to use a presenter. Decorator design pattern is a way of adding additional behaviors or responsibilities to an object dynamically without subclassing. The decorator pattern is a very good example of the Open-Close-Principle (OCP) which states that an class is closed to modification but open to extension. In short, the decorator pattern is a composing operation whereas the presenter pattern is a decomposing operation.
My only question might be a little out of scope for this episode, but how would one go about adding a blank presenter file for inclusion when scaffold is run?
Wow, so this is the best day of my OSS-writing life.
Kevin: Cells is a much bigger idea than Draper. Draper's decorators are forcing Ruby objects into the existing view layer. Cells are almost self-contained MVC systems.
JamesW: Models are about data and business logic, not presentation. In your example, deciding on the default avatar is a presentation issue, not really business logic. For XML or JSON it would be more logical to return an empty string from the default avatar, rather than referencing an irrelevant image.
Joel: I still need to work on the CanCan-compatibility, sorry I haven't had much OSS time lately. If Ryan has any suggestions I'll jump to implement them.
It's about time you got some financial reward for all your hard work.
I have an issue about this episode though. Surely the logic that is being placed in the decorator belongs in the model?
I see things like if there is no uploaded avatar then provide a default avatar as business logic and default values provided by the model can be used for xml, json responses, rake tasks etc...
I feel this approach goes against the grain and I feel that this sort of approach is a solution to a deeper problem which is that not enough developers know where to put their logic.
In other words I can't help thinking that this seems to be fixing symptoms of bad coding rather than providing a solution to the cause. We have models, why not use them?
I don't like coupling the name of the model to the name of the presenter. What if you have multiple ways of displaying users, or if you more than one user-like objects?
A simple solution might be something like:
<% present @admin, with: ProfilePresenter do |presenter| %>
<p><%= presenter.website %></p>
<% end %>
This is fantastic, glad to see you'll be making some more money for all your hard work. I'm very happy to go pro. Quick question though, I was very excited to see how you handled your payment, subscriptions, etc. by looking at this app on github. But for some reason, it doesn't look like it's updated there. I see no routes, controllers, models, engines, or anything that builds the subscription/payment parts. How are you handling this/can we view this code?
any reason you're using a base class instead of a module, for the base presenter? i'm still pretty early in my rails career (~1yr), but I thought "the rails way" was to use modules instead of inheritance.
@dicky - It sounds like the cookie is always being set as permanent. So, I'd check the 'if' statement that sets the cookie to and make sure it's actually doing what you'd like it to do. I'm sure if you post the code (here, or for example, on RailsForum,) someone will help you out.
I can confirm what tatumszymczak said. It doesn't work for other ips in the network, be them PCs or mobile phones (HTC Desire for example).
I have changed from localhost to my network ip, so it should be working.
@Ryan Bates can you look into that man? Thanks
Edit: Nevermind, I discovered what the error was. I forgot to change localhost in the file application.html.erb (layouts) too. Hope that helps you folks :)
I am new to Ruby and Rails and while trying to get up to speed, I came across your site and watched your screencasts on Authentication (Sorcery) and Authorization (Declarative authorization).
This really simplifies much of the menusha associated with Authentication while allowing for some flexibility.
You did an outstanding job on presenting the information in a simple and easy to follow fashion. Kick ass!
I found that if I put --drb in both .rspec and GuardFile, there will be a warning that says "port is in use", so I move the --drb into GuardFile and left --color in .rspec, that warning is gone.
BTW, set :cli => "--color --format nested --fail-fast --drb" will makes the output of Rspec more readable and clear
I just use Spork each_run method to reload model files that Ryan mentioned in this screencast.
Spork.each_run do
# This code will be run each time you run your specs.
# Reload all model files when run each spec
# otherwise there might be out-of-date testing
require 'rspec/rails'
Dir["#{Rails.root}/app/controllers//*.rb"].each do |controller|
load controller
end
Dir["#{Rails.root}/app/models//*.rb"].each do |model|
load model
end
end
I think spork caches classes. That means you need to reload spork whenever any of your non-view app/ files change. For example, I have this (and similar lines) in my guard 'spork' block:
I had the same problem. Could not get models reload. I tried to a bunch of fixes I found from searches, but nothing worked. I eventually had to abandon spork. Sucks too cause it did speed it up a bunch.
I'm not having any luck it seems at using spark in conjunction with factory_girl. Factory girl causes my models not to be evaluated again after a change. Have you experienced anything like this using spark and factory_girl?
Looks like MetaWhere isn't compatible with Rails3.1. Is there another gem like MetaWhere that works with 3.1? There is Squeel, but it uses a funky syntax, and I'd rather stick with something with a syntax that somewhat resembles standard Ruby & Arel.
Hey guys - anyone else try to get it to admin your User or AdminUser models?
It seems to just edit the fields directly, and shows the encrypted password - where RailsAdmin would understand Devise and give you a regular password field that would work for password changes.
Ryan,
I am so pleased that you have decided to offer more screencasts. Thanks for all your great work, you have passed on an incredible amount of knowledge over the years through these screencasts.
If you click on the big "Railscast" logo on the top left hand corner...you'll get "both types".
I agree having a link in the right hand nav would be useful, though!
Suggestion: where you've got Types, "Free Episodes" and "Pro Episodes" in the right hand navigation, how about a "Both Types" option?
Hi, question. I'm using rspec, and added the 'include ActionView::TestCase::Behavior' as you recommended. However, I'm getting a "undefined method 'setup'" error from action_controller/test_case.rb:12. I am using Rails 3.1.
Any thoughts on what I'm doing wrong?
Sounds neat, but all the examples look like a single resource. What about more complex examples; such as a User has_many Posts... In the view one might have a @user.posts.each |post| do ... how do you get a decorator object for those?
Presenter design pattern aka presenter refactoring is a way of simplifying controller logic by extracting it out into its own class which has one or more methods. Thus, making it easier to test controller logic by usually transforming each assigned instance variable in a controller action into its own method within the presenter class. Anytime you see a controller action which has many instances variables, it needs to be refactored to use a presenter. Decorator design pattern is a way of adding additional behaviors or responsibilities to an object dynamically without subclassing. The decorator pattern is a very good example of the Open-Close-Principle (OCP) which states that an class is closed to modification but open to extension. In short, the decorator pattern is a composing operation whereas the presenter pattern is a decomposing operation.
Draper describes itself as a Decorator. Can anyone explain the difference between a Presenter object and a Decorator object??
Awesome information. Glad I subscribed =]
My only question might be a little out of scope for this episode, but how would one go about adding a blank presenter file for inclusion when scaffold is run?
Wow, so this is the best day of my OSS-writing life.
Kevin: Cells is a much bigger idea than Draper. Draper's decorators are forcing Ruby objects into the existing view layer. Cells are almost self-contained MVC systems.
JamesW: Models are about data and business logic, not presentation. In your example, deciding on the default avatar is a presentation issue, not really business logic. For XML or JSON it would be more logical to return an empty string from the default avatar, rather than referencing an irrelevant image.
Joel: I still need to work on the CanCan-compatibility, sorry I haven't had much OSS time lately. If Ryan has any suggestions I'll jump to implement them.
A presenter is a class which knows about both a model and the view. It can help clean up complex view logic. Watch the episode for more details. :)
Thanks for catching this, I'll update the show notes to mention this.
I will be releasing these changes as open source, keep an eye out for it.
Thank you for spotting this, fixed!
If I am overriding
initialize
then I will use a superclass. Otherwise I would have made this a module.What's the best way to handle ActiveAdmin's resources in Rails 3.0.5 under a scope?
ie:
example.com/my_app/admin
I got the routes for the pages themselves, but Images and CSS don't come through. Suggestions?
Any reason you chose Draper over Cells which has 116 votes? They appear to address the same issues.
It's about time you got some financial reward for all your hard work.
I have an issue about this episode though. Surely the logic that is being placed in the decorator belongs in the model?
I see things like if there is no uploaded avatar then provide a default avatar as business logic and default values provided by the model can be used for xml, json responses, rake tasks etc...
I feel this approach goes against the grain and I feel that this sort of approach is a solution to a deeper problem which is that not enough developers know where to put their logic.
In other words I can't help thinking that this seems to be fixing symptoms of bad coding rather than providing a solution to the cause. We have models, why not use them?
Please correct me if I'm mistaken, but shouldn't your present definition in the ApplicationController look like this?
The object comes before the template in the initialize method of the BasePresenter.
The "with" option would be fine too, but the "present" helper in this screencast already takes an optional second argument for this specific purpose.
On Windows, I get the error
> 'spork' is not recognized as an internal or external command,
> operable program or batch file.
When I ran bundler, though, spork installed 3 windows gems
I don't like coupling the name of the model to the name of the presenter. What if you have multiple ways of displaying users, or if you more than one user-like objects?
A simple solution might be something like:
Awesome screencast. I love the from scratch episodes and I also enjoyed the inclusion of Test::Unit.
can you explain what is Presenters ?
Ryan,
This is fantastic, glad to see you'll be making some more money for all your hard work. I'm very happy to go pro. Quick question though, I was very excited to see how you handled your payment, subscriptions, etc. by looking at this app on github. But for some reason, it doesn't look like it's updated there. I see no routes, controllers, models, engines, or anything that builds the subscription/payment parts. How are you handling this/can we view this code?
Guess you need to change the copyright notice at http://railscasts.com/about .
The purpose of the 'pro' accounts would be defeated by the present Copyright statement :)
any reason you're using a base class instead of a module, for the base presenter? i'm still pretty early in my rails career (~1yr), but I thought "the rails way" was to use modules instead of inheritance.
@dicky - It sounds like the cookie is always being set as permanent. So, I'd check the 'if' statement that sets the cookie to and make sure it's actually doing what you'd like it to do. I'm sure if you post the code (here, or for example, on RailsForum,) someone will help you out.
rake install does not run rake build. at least not on my local machine.
neat, clear, interesting as usual, they're nice to watch just to appreciate the quality!
prepend_view_path
is awesome, I wish I had that on a big messy app I picked up some months ago, - thank youI can confirm what tatumszymczak said. It doesn't work for other ips in the network, be them PCs or mobile phones (HTC Desire for example).
I have changed from localhost to my network ip, so it should be working.
@Ryan Bates can you look into that man? Thanks
Edit: Nevermind, I discovered what the error was. I forgot to change localhost in the file application.html.erb (layouts) too. Hope that helps you folks :)
this episode looks obsolete after #246, but still good exercise, thank you!
I agree
great! just what I needed, thanks again
Thanks a lot. At last, I got it! :)
Hello, I'm trying to delete a record with the code
but the link does not work, should we declare it otherwise? Thank you.
Ryan,
I am new to Ruby and Rails and while trying to get up to speed, I came across your site and watched your screencasts on Authentication (Sorcery) and Authorization (Declarative authorization).
This really simplifies much of the menusha associated with Authentication while allowing for some flexibility.
You did an outstanding job on presenting the information in a simple and easy to follow fashion. Kick ass!
Best,
Mike
I found that if I put --drb in both .rspec and GuardFile, there will be a warning that says "port is in use", so I move the --drb into GuardFile and left --color in .rspec, that warning is gone.
BTW, set :cli => "--color --format nested --fail-fast --drb" will makes the output of Rspec more readable and clear
I just use Spork each_run method to reload model files that Ryan mentioned in this screencast.
Spork.each_run do
# This code will be run each time you run your specs.
# Reload all model files when run each spec
# otherwise there might be out-of-date testing
require 'rspec/rails'
Dir["#{Rails.root}/app/controllers//*.rb"].each do |controller|
load controller
end
Dir["#{Rails.root}/app/models//*.rb"].each do |model|
load model
end
end
I think spork caches classes. That means you need to reload spork whenever any of your non-view app/ files change. For example, I have this (and similar lines) in my guard 'spork' block:
watch(%r{^app/models/.+\.rb$})
Did you ever get anywhere with this question? I'm struggling with the same thing.
Thanks for the screencast!
Can this be combined with CanCan and does it allow logins using OpenID?
Can you report this as an issue on https://github.com/pry/pry/issues with an exact explanation of your problem ?
I had the same problem. Could not get models reload. I tried to a bunch of fixes I found from searches, but nothing worked. I eventually had to abandon spork. Sucks too cause it did speed it up a bunch.
I just realized it's why it's not stopping. I had moved to passenger. Did you find the solution?
I'm not having any luck it seems at using spark in conjunction with factory_girl. Factory girl causes my models not to be evaluated again after a change. Have you experienced anything like this using spark and factory_girl?
Looks like MetaWhere isn't compatible with Rails3.1. Is there another gem like MetaWhere that works with 3.1? There is Squeel, but it uses a funky syntax, and I'd rather stick with something with a syntax that somewhat resembles standard Ruby & Arel.
Hey guys - anyone else try to get it to admin your User or AdminUser models?
It seems to just edit the fields directly, and shows the encrypted password - where RailsAdmin would understand Devise and give you a regular password field that would work for password changes.
I want to use this to admin Users too :)
ideas?
found it:
I had to set
:cli => '--drb'
as well as bootstrap cuke's env.rb. Working fine now =)