Sign in through GitHub

Please read for an updated status on RailsCasts:

Learn more or hide this

Ryan Bates's Profile

GitHub User: ryanb

Site: http://railscasts.com

Comments by Ryan Bates

Avatar

I agree! Gary's Destroy All Software is awesome and a good compliment to RailsCasts. :)

I usually do not cover theory but try to focus more on practical solutions to common problems. This episode is more of the former - I may do more of these occasionally.

Avatar

This is due to the has_secure_password behavior. We could extract this into the Authentication class however I don't know if that tradeoff is worth it.

Avatar

True but then you need to worry about every time you save the record after that. I am very careful whenever saving without validations.

Avatar

Great points everyone, this is actually the topic of my next episode!

Avatar

This is just a quick way to get a "user" attribute. It also saves me from having to define the "initialize" method here.

Avatar

I'm not sure if I'm understanding your question correctly. You could call @user.gender in the view if you want to put the array in a method.

Avatar

Have you tried using the rescue_from method for this?

Avatar

I am hoping to cover authenticating/authorizing an API soon. Thanks for the suggestion.

Avatar

Fixed, thanks for bringing this to my attention.

Avatar

Fixed, thanks for bringing this to my attention.

Avatar

I recommend using Postgres for full text search to start off, and then you can always switch to something like Elastic Search later if you need to. It is just so convenient to keep the full text search in SQL.

Avatar

Yes, I hope to cover Facebook and Twitter integration in future episodes.

Avatar

Thank you for letting me know about this issue. Which browser are you using? Also try right-clicking the video and switching between HTML 5 and Flash, does that change it?

It seems to be working okay here in Safari.

Avatar

Thanks for the tip. One side effect of this approach is that you will not be able to weight certain columns AFAIK. Unless maybe you repeat them when building the tsvector?

Avatar

Thank you for the tips. Very useful information. I had not heard of Valkyrie before but looks more convenient than Taps.

Avatar

Sorry about this issue. I will add a note and update the code to explain this.

Avatar

Thanks for sharing, I wasn't familiar with Sunzi. I'll add it to the list of alternatives.

Avatar

I do hope to cover other JavaScript libraries such as Knockout, Spine, and Ember in the future. Not certain when or in what order. Thanks for the suggestion.

Avatar

I'm calling Entry.update (class method) so it has no context of the entry record I'm trying to update, which is why it is necessary to pass params[:id] to it. The params[:entry] contains the attributes that will be updated.

Avatar

I hope to cover Twitter Bootstrap in the future, thanks for the suggestion.

Avatar

Good point, I'll look into this and consider covering it in part 2.

Avatar

Fixed the link and I'll look into the cut-off issue. Thanks for letting me know about these.

Avatar

Thanks for mentioning this. I was debating between backbone-on-rails and backbone-rails, both are great projects. Went with backbone-on-rails because of the simpler generator was easier to build off of.

Avatar

Make sure your Rake task is loading the full Rails environment: task :foo => :environment. It should have access to the key/value store then.

Avatar

It depends on what you're doing in the middleware, but usually it will only add a quick "if" condition and a couple method calls to the stack. In theory it is slightly slower but nothing that will be noticeably slower.

Avatar

I am trying to avoid renaming the titles of the episodes when I revise them, so I understand that can make it a little misleading.

Avatar

RABL is similar, and I will likely do an episode on it in the future since it is different enough from Jbuilder. What I like about Jbuilder is its simplicity (it is just two small files). But RABL has more to offer in its interface.

Avatar

Good question. You can't use the cache helper method because that is designed to work with ERB. However you can use the read_fragment and write_fragment methods to manage the cache directly.

Avatar

Great point. Sometimes you can get by with making the status panel more generic such as "My Account" so it can work for any situation. However that isn't always wanted.

Alternatively you can use JavaScript to load the dynamic content. See Episode 169: Dynamic Page Caching on how to do this. I plan to revise that episode in the near future.

Avatar

In private_pub, each subscription has its own unique signature/key. This means you can do something like auto-expire it after a period of time. If each chatroom has only one unique secret key then it is not possible to have control over each individual subscription.

Avatar

Channels aren't necessarily created, they are just a name given to determine which messages are sent to which users.

Avatar

SSL isn't fully supported yet, but I hope to add it in a future version. See https://github.com/ryanb/private_pub/issues/18

Avatar

Fair point, but I think that cost is worth it for the ease of transition.

Once one starts to get their feet wet and become curious about separating Oh My ZSH from ZSH they can browse the ~/.oh-my-zsh/lib directory and it's quite easy to see all that it is configured.

Avatar

I don't care for this feature as much. It's a bit too greedy. Primarily because every time I try to do autocompletion it will try to use the directories there.

Avatar

From what I can tell, creating a theme in Spree is very similar to customizing the application like I showed here. The only difference is that you're working on an engine instead of the application. Check out the blue theme and the Rails Dog Radio theme for good examples.

Avatar

It is a bit slow in development mode, see the performance section in the readme here for how to improve it. Also you may want to try Active Reload.

Avatar

I didn't find this to be the case on my setup, but you may be right as I'm not the most proficient at Ubuntu. Thanks for mentioning.

Avatar

More episodes on deployment are planned, thanks for the feedback.

Avatar

Haha, had a bad cold that really messed with my voice.

Avatar

Good question, needing to run bundle exec depends on how your system is setup. Here I'm only installing gems through bundler (there is no Rails gem installed on the system outside of Bundler) so I need to use bundle exec. It's also a good idea to always use this to ensure you're working with the proper version of the gem.

On my development machine I am using Oh My ZSH with the Bundler plugin which sets up aliases for these commands so I don't need to type in "bundle exec" in development.

Avatar

I'm not certain. Is the mail delivery method working? Try experimenting with it in the Rails console on your production server and see if it sends email.

Avatar

Receiving exceptions by email is great because you can set it up to be notified when this happens. Also if you're providing an in-app interface for browsing exceptions you need to worry about locking it down. Having a database of exceptions is handy, but Gmail search works pretty well.

Avatar

Even just a few tests are better than no tests at all, so start off with the easiest ones to write that will get you the most "bang for your buck".

I find these are generally the high-level request specs like I show in episode 275. Writing request specs is nearly as easy as walking through the app manually, and once it's done you won't have to manually test it next time.

Avatar

This is a controversial subject, but I don't subscribe to the "one assertion per test" way of thinking. It can really slow down tests if you're not sharing data between assertions, especially in high-level request specs. RSpec 2 shows you exactly what line failed the assertion so it is easy to spot in a multi-assert clause.

Avatar

Right, without PJAX I would normally add remote: true option to a link and respond with some JavaScript that renders out only exactly what I need, but that is quite a bit more work. So it is a tradeoff of performance for convenience.

Avatar

Good questions.

1) The save_with_subscription method is doing a valid? check and therefore does not raise an exception when validation fails. I am doing save! inside the valid? check because if the data somehow got invalid between then and now I want to know about it.

2) Handling cases where save fails is tricky because the transaction has already been placed. I suppose you could do an automatic void but then there's always the possibility of that not going through. I think this is better to be handled manually. If save fails then it will raise an exception and hopefully there is something setup to notify you when an exception occurs so you can handle the situation manually (such as voiding the transaction).

Avatar

Thanks for posting this, I had forgotten about the prop method.

Avatar

I wish there was a good solution for this but I can't think of any alternative recurring payment method that will work in Germany. If you have suggestions please let me know.

Avatar

Yes, I will be adding a PayPal checkout option soon, stay tuned.

Avatar

I will be adding a PayPal checkout option soon, stay tuned.

Avatar

I have not yet made the Pro features open source, but i plan to at some point. I just want to make sure it's air tight before I do because I'm dealing with more sensitive information.

Avatar

PayPal support will be coming soon. Thanks for your interest in RailsCasts Pro.

Avatar

To do this you can place any sensitive data config files in the shared directory on the server and then symlink/copy them over upon each Capistrano deploy. See the how I'm doing it here for an example.

Avatar

I don't plan to switch to Stripe since I already have Braintree setup. They're both great though.

Avatar

I'm using Braintree at the moment, but will be adding PayPal as an alternative checkout option soon.

Avatar

This is using the new hash syntax present in Ruby 1.9.2. If you are using Ruby 1.8.7 you would need to convert this to the old hash syntaxrender :nothing => true.

Avatar

Sounds like a fun idea for a future episode, thanks for the suggestion.

Avatar

Glad you like the revised episodes. The 3.1 tag is for episodes where the main topic is a feature of 3.1 and cannot be applied to 3.0. It is true one would need to translate the CoffeeScript into JavaScript, but other than this the functionality is the same.

Avatar

Pagination is tricky because I'm not certain how you would sort across pages. You may want to do simple up/down arrow buttons that increment/decrement the position instead of drag + drop sorting.

Avatar

Thanks for the suggestion. Pushing API requests into a background process is a good thing and would make a good episode. Good idea.

Avatar

Thanks for the suggestion. I plan to cover TTD more in future pro episodes.

Avatar

I don't think so, but I haven't tried it. VCR needs to stub out the HTTP request, so that needs to happen in Ruby. I don't think the Capybara Selenium driver uses Ruby at all to perform the HTTP requests. It instead communicates with Selenium at a higher level. I believe the same goes for Capybara Webkit and other alternatives.

That said, what you can do is setup a proxy Rack server which all remote requests go through. This can forward all HTTP requests to their remote destination using Net::HTTP and therefore use VCR to record it. It would look like this: Capybara > Selenium > Rack proxy server > Remote server.

Avatar

Since VCR only stubs HTTP requests it won't work over an SSH tunnel. However what you can do is setup a proxy server that is before the SSH tunnel and have VCR record requests that go to that server. I haven't actually tried this, and it's a bit advanced, but hopefully it will give you some ideas.

Avatar

The delivery_method isn't a method that you define. It is normally set to :smtp or :sendmail depending on what you want to use to send email. See the guide for further details.

Avatar

You also need to worry about HTML escaping when putting HTML directly in a string. The content_tag method handles that for us, unless we're doing something more with that string. "<span class='none'>None given</span>".html_safe just feels ugly.

Avatar

If you have more ERB tags than HTML tags, use a decorator. ;)

I also like to think about a partial being at an object scope (a _post partial) but a decorator method being at the attribute scope (a post.title method). It's finer bits of logic.

Avatar

This is one reason I prefer keeping presenters in the view layer as I discuss in episode 287. It helps for cases like pagination.

In this specific case you could create a UserDecorator#posts method which loops through the posts, fetches the decorator for each one, and then renders a post partial with the decorator.

Avatar

Cells feels a bit heavy for this case being like mini controllers and views. I just want an object that I can place some view logic into.

Avatar

Good point, there is some logic I can see going in the model here. Primarily the full_name vs username portion. Those are both attributes on the model and feels ugly in the presenter.

The only other methods which don't have an HTML tag in them are avatar_name and member_since. In these cases, I ask myself, is there a case I may want to embed markup into the logic? I can see treating the default avatar image special, perhaps giving it a CSS class to make it look different, not linking it, etc. Same with the member_since method. We may want to make the year italic for example.

That said, this may be a bit of a pre-refactoring and doesn't fallow YAGNI since that markup requirement doesn't exist. I can see that point.

As for having similar logic in xml/json responses. Those are also views and can have their own presenters with their own set of logic. If there is duplication in logic then it's a sign it should go in the model or maybe a shared module.

Avatar

I prefer the presenter be a bit verbose in the view so that it is obvious we are doing something special here beyond calling model attributes. Otherwise one might think calling user.twitter would just return the twitter username and not handle the link, etc.

That said, you could do something like smart partials where the object passed to the partial is a presenter instead of a simple object. But unless Rails adopts presenters as part of their stack, I prefer they be explicitly declared whenever used.

Avatar

Even though the topics will be more advanced, they will not necessarily be more detailed. I am unable to produce a half hour episode each week unfortunately, but I will consider revisiting specific areas of presenters in future pro episodes to address the scenarios you mentioned. Thanks for the feedback.

Avatar

It has important differences such as making presenters in the view instead of the controller, and passing the template object through. Overall I think the implementation is simpler and more flexible, but it's up to you to decide which you prefer.

Avatar

I should have the first revised episode up later this week. I also hope to be more active in the comments as RailsCasts becomes my full time job. Almost there.

Avatar

I would have to see the stack trace to find out where this to_presenter method is coming from. Perhaps there is another present method already defined that has different functionality.

Avatar

Sometimes the pro episode linking takes a few minutes after subscribing. If it doesn't start working let me know.

Avatar

Both types are the default search option. If you select a type you can cancel that by clicking the "x" in the Filter section about the episodes list.

Avatar

The setup method is only for Test Unit. If you're using RSpec you can do before(:each) instead.

Avatar

I would probably make my own generator for this. See episode 218 for details. This generator can wrap the scaffold generator if you want.

Avatar

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

Avatar

Thanks for catching this, I'll update the show notes to mention this.

Avatar

I will be releasing these changes as open source, keep an eye out for it.

Avatar

If I am overriding initialize then I will use a superclass. Otherwise I would have made this a module.

Avatar

Rails Admin looks great as well, but I didn't feel it was ready to be covered. A gem hasn't been recently released. I will probably cover it in a future episode after it reaches a stable point.

Avatar

You can change the current_user_method in the config/initializers/active_admin.rb file to use something else. I'm not sure what other dependencies Active Admin has on Devise though.

Avatar

I don't do controller or view tests because I feel they overlap too much with integration tests. Usually if something is too complex to go in an integration test then it should be moved into a model or helper and tested there in isolation. This makes it easier to handle a lot of branching paths and such as well.

I'm not very strict on refactoring test code, I feel it's better to be more direct there to reduce the possibility of bugs and odd dependencies. But when I do see a lot of duplication I like to move it into a module in the spec/support directory and do config.include in the spec_helper.rb

Avatar

I think it's still good to have a Timecop.return statement in spec_helper.rb in case something slips through, but I do think the block syntax is great for larger test cases where you want to isolate where it is frozen.

Avatar

I can't remember now why I chose FakeWeb over WebMock when I used it in railscasts.com, but it definitely does look more full featured. Thanks for bringing this up. Time to research it.

Avatar

Thanks for the link! I do hope to cover VCR in a future episode which is more about testing with an external api.

Avatar

I see TDD as adopting the philosophy that writing tests/specs/etc is an integral part of one's development process, not some special separate step -- and yet, all the literature (books, blogs, screencasts) illustrates development without the testing, unless the testing tools are themselves the subject matter, and then you kind of see it in isolation.

This was the motivation behind my tweet asking if others would like to see testing integrated into every episode, almost showing how I would solve the problem in the real world.

However, the issue is that the episodes would be too long, and it would muddy whatever else I'm trying to teach. This is why I opted to keep the testing episodes separate.

I almost scrapped this episode because it was difficult to get the flow right. This is because the example was not contrived and optimized for presentation. But now I see there is a lot of value in non-contrived examples.

I've been slow to adopt TDD practices, not because I need any more convincing of their benefit, but because I feel like I don't have a real understanding how it should be done (and even moreso in Rails development, where there's a lot of support infrastructure that needs setting up to spin up the app's environment, test database, fixtures, mocking out authentication, etc, before you can even get started running the tests!) and that frustrates me.

I have struggled with this too, but I feel my testing workflow is finally at a point where I'm confident to share it with others. The way I show how to test here is relatively easy once you get past the initial hurdle.

Avatar

I didn't know about the :broken tag, thanks for bringing it to my attention.

Avatar

I have looked into the one-assertion-per-test style but could not make it work for me. The test suite can easily become very slow. I have not heard a convincing argument for it. Some say it makes it much easier to determine what failed, but RSpec makes it easy to see which exact line is causing the failure.

Avatar

I agree. SimpleCov is awesome. I considered including it but decided to take it out at the last minute because it made the episode too long.

Avatar

Hmm, that is strange. It is working for me as you saw in the episode. It may be something specific to the RSpec version.

Avatar

I didn't use scaffolding in this episode, however I did use several generators (controller, mailer, migration). I think most Rails developers use these generators.

That said, I do scaffolding in my everyday development through Nifty Generators. I encourage everyone to create their own scaffold generators to improve their workflow.

I think scaffolding just gets a bad rap because the built-in scaffold generator is near useless in everyday Rails development.

I do hope to incorporate more of my development workflow into these screencasts. Maybe do some TDD at the beginning. We'll see.

Avatar

That's a good point. When I mentioned the edit action not being truly RESTful I am not hiding a better solution, but more pointing out I am intentionally not following REST here. I considered a couple alternatives when preparing this episode.

What I consider the "proper" way to do this would be to have two controllers/resources. One being PasswordResetRequests with new/create actions, and one being "UserPasswords" with edit/update actions. But two controllers seem overboard for this one feature.

Alternatively we could handle the editing of the password in the Users controller, after all it is the User model we are working on, but if we add a way to edit the user profile then there is a conflict here. Suddenly the edit/update actions would need to have several "if" conditions determining if it is editing the profile or resetting the password. Not only that but it is mixing the password reset feature into other parts of the app. This would quickly get messy.

REST is actually more about the URLs than it is controllers, so we could keep everything in the same controller but add custom URLs. However, this would require 4 complex lines in the routes file instead of the simple resources :password_resets. I do not like that solution either.

So, we're left with leaving everything in a PasswordResets controller which follows the REST pattern but it is not truly RESTful because it is working on two separate resources. Still I consider it to be the best solution for this problem. Maybe there are ways the Rails router itself can be improved to handle these situations.

Avatar

Thanks for the feedback. I will try to do both because I think both have their place. I too try to reduce the number of gems I use in a project because having many dependencies has bitten me in the past.

Avatar

Very good point. If you're giving an error that the email address is registered then there is no point in making the password reset message generic. In that case you might as well go with a more user friendly approach and state that the email address was not found.

I mentioned in the screencast that you may want to change that experience depending on the app.

Avatar

I too prefer Omniauth for authentication, but not everyone wants to use external services for auth. Even when using Omniauth it's good to provide a fallback for username/password if users don't want to link the account to twitter/facebook.

Thanks for the feedback regarding gems vs. from scratch. I try to cover both because I think they both have their place. There are many cases where gems don't quite fit and require so much customization that the dependency is not worth it. Authentication is often that way for me.

Avatar

Sorcery has been on my list to check out, but I haven't yet. Thanks for the reminder!

Avatar

I do like it that Authlogic does not try to take over views, but I think there are better solutions out there. It always bothered me how much it knows about the current request/session, and it felt a little over-complicated.

Avatar

I think that the user record should probably store their log-in OS/Browser checksum to validate any returning users.

I find users often want to log-in through multiple devices at the same time. Also if one can steal the cookie it would not be difficult to spoof their user agent.

I think it depends on the app, if you are making a banking site then security is much more critical and then you probably shouldn't listen to me. :)

Avatar

I also agree with @Iain and @introspectif that there are too many security loopholes to remember to close each time to build from scratch.

Are there any specific security loopholes you see that would be difficult to remember? The most common security issue is hashing the password which is now handled nicely in Rails 3.1 with has_secure_password.

Also I would suggest adding an index on the email column of the user model since every time someone logs in you are performing an

Good point! The auth_token should be indexed as well.

Avatar

However, I think you have too much logic inside te password_resets_controller. Especially the 2.hours part.

I agree that should probably go somewhere else, maybe in the User model or a separate config. I would hesitate to create a PasswordReset class just for this. True that it might fit the RESTful paradigm when there is a resource backing it, but I don't think the end result would be clearer or easier to read.

And I agree with @introspectif that Devise is childishly easy to customize. So much so that I would never write my own authentication. There are too many security pitfalls to remember.

Good point about security. I personally feel Devise gets messy when needing to customize the behavior, however this may be just a personal opinion. I would love to see something lower level that can handle all of the security measures without taking over controllers. Something along the lines of Authlogic but which followed MVC a little better.

Avatar

You're right, it is easy to customize Devise views. My point being that if you're going to customize this anyway, I feel it's a good portion of the work involved in adding these features from scratch. I also find I often need to customize more than this in Devise, such as overriding certain controller actions, and then things get messy.

Avatar

Great point. You can store the user id in a signed cookie instead of generating a custom token. However for permanent cookies I prefer to keep it separate so it gives you more control over when to expire the session. For example you can reset the auth_token every time someone resets the password, or maybe every time someone logs in to automatically log-out previous ones. There's a lot more flexibility here.

It is also possible to change when the session cookie expires, but I think it's better to stick with a separate cookie.

Avatar

That is very strange, it is not behaving this way for me. Maybe it's a different version of Nokogiri, what version are you using? I am using 1.4.6 in the screencast.

Avatar

I prefer not to add these kinds of abstractions until I need them. Usually if I need to customize the options it will be to add or remove one option which will cause a lot of duplication. I think this kind of abstraction would be better, but too much to show in the episode.

ruby
def markdown(text, options = {})
  options.reverse_merge!(
    :hard_wrap => true,
    :filter_html => true,
    :autolink => true,
    :no_intraemphasis => true,
    :fenced_code => true,
    :gh_blockcode => true,
  )
  options.reject! { |k, v| !v }
  syntax_highlighter(Redcarpet.new(text, *options.keys).to_html).html_safe
end

Then you pass true/false options hash to modify the defaults. But the point is there are different ways to abstract this out, and we can't tell the best way without seeing how it needs to be customized.

Avatar

Oops! Fixed. Thanks for reporting.

Avatar

Something like this in the ApplicationController.

ruby
def authenticate_user!
  if current_user.nil?
    redirect_to login_url, :alert => "You must first log in to access this page"
  end
end
Avatar

Yes, CanCan just relies on a current_user method. It is compatible with pretty much any type of authentication.

Avatar

The validates alternative would be.

ruby
validates :password, :presence => {:on => :create}

Both alternatives are longer so I don't know if they are necessarily better. The other way may be deprecated in 3.1, I haven't checked yet.

Avatar

Yes, it is safe to store the user_id in a session. If you're using cookie based sessions then the client can read the data inside, but they can't write to it. Basically you don't have to worry about someone changing the session, but you do have to be careful to not store sensitive information in there (such as the user's passwords).

Avatar

Are you referring to flash.now.alert=? That was working in the episode and is available in older versions as well.

Avatar

On the surface they do basically the same thing: redirect to https, but at different levels. Apache/Nginx will redirect before it ever hits the Rails app, so it will be quicker and it won't go through the Rack middleware stack at all.

The force_ssl call in the controller happens in a before_filter so it will happen later. The main benefit of this is that you can add/remove it for certain actions and use any Ruby logic you want. If you want every page in your app to use SSL then doing it at the web server level is probably best.

There is also a config.force_ssl = true option you can place in your app config which will use middleware and redirect every page. That is closer to Apache/Nginx solution but is nice if you don't have access to that config such as on Heroku.

Avatar

Good question. The import path seems to be the app/assets/stylesheets directory, but I don't know how to change it in 3.1. Maybe someone else will be able to enlighten us.

Avatar

Yeah, too bad CodeRay doesn't include a scanner for it. Ping me on Twitter if anyone is interested in making one.

Avatar

Thanks for reporting this. I'll look into fixing this problem.

Avatar

Thanks for the feedback guys. For the logo I went with an arcade style design to give it a techno and fun feel. I realize it's not everyone's kind of style but I encourage you to give it some time and it may grow on you.

I'm open to other design ideas throughout the site, so if you have specific suggestions on how the design can be improved please let me know.

Avatar

Good point. I had forgotten to move it since switching to the new resolution. I'll try to remember!

Avatar

I didn't realize that ProjectPlus was considered more up to date. I didn't see a GitHub repo for it and assumed it was equally dead. Hmm.

Avatar

Good point about destroy/delete. I get caught up in the destroy convention in the Rails world and forget it's not standard everywhere.

Avatar

That one will always have a special place in my heart too. :)

Avatar

Interesting. I didn't know nodejs was required on Ubuntu but I guess it needs something to compile CoffeeScript. Thanks for reporting this.

Avatar

Hmm, that is strange. I used pretty much the default settings of ffmpeg2theora to make the ogv format. Maybe it doesn't like the variable frame rate movie it is given to start off with. Time to do some testing.

Avatar

Haha, glad to see the code formatting is working. Thanks! :)

Avatar

Hmm, the H.264 video should be passed to the GPU in recent hardware. Are you using FireFox maybe? You can access a low-res version by clicking the m4v download link or subscribe to the iPod version of the feed on iTunes.

Avatar

Done! Thanks for the suggestion.

Avatar

Thanks for the feedback James. Others have mentioned this as well. I plan to change the Watch Episode button so it starts playing the episode immediately. Let me know if you have any other suggestions.

Avatar

I haven't used ree much so I'm not certain how the performance compares with Ruby 1.9.2. I've been very happy with 1.9.2 though.

Avatar

Hmm, not sure what's up with the name problem. Sorry about that. I'll look into it.

Avatar

Thanks for the feedback Javi. In the past there were complaints about the episode page being too heavy because there were so many comments. Once I get the comments cleaned up I will consider bringing them back to the main episode page.

Avatar

Thanks for the feedback, I'll work on fixing this problem soon.

Avatar

Thanks for the feedback, I am considering adding this feature. For encoding I used a combination of HandBrake, ffmpeg, and ffmpeg2theora. I plan to script my workflow and put it on GitHub soon.

Avatar

@Sairam, Ancestry has an ":orphan_strategy" option you can pass to determine how to handle the child records when the parent is deleted. Check out the readme for details.

@Aditya Them message content is already escaped when the message partial is rendered, so marking it as html_safe is fine here.

@Skully, yes, I did take a look at awesome_nested_set and the nested_set fork, but I liked Ancestry a bit more.

@jui, You can call the "depth" method on the model to determine the level and change the rendering accordingly. Alternatively if you can do this with CSS, change the styles depending on the ".nested_messages" depth.

Avatar

@Jan, cool, I'll check out Evergreen. Thanks for the suggestion.

@Aaron, make sure that you're loading the files properly in the jasmine.yml file. Sounds like either jQuery isn't loaded or it's conflicting with something.

@Celestino, Jasmine isn't specific to the run environment, so you can use it without a browser as well. It is the Ruby gem which uses a browser based run environment.

Here's an example of using Node.js to test a jQuery plugin.

http://digitalbush.com/2011/03/29/testing-jquery-plugins-with-node-js-and-jasmine/

Avatar

@ybart, oops, I forgot that. It's up there now.

@Jingwen, The approach I show here is very similar to Pusher, but I don't know if they use EventMachine internally. the RackAdapter inside of Faye does use EventMachine, the Node.js server version does not.

The beautify of this approach is that you don't have to worry about any of this. Your Rails app does not need to use EventMachine because it just sends a quick post request to Faye.

@Javi, done.

Avatar

@Oleg, I haven't tried Juggernaut because Faye worked so well for me and did exactly what I needed, but Juggernaut does look great as well. I should give it a try. Thanks for the suggestion.

@ybart, application.js is included automatically by the :defaults option.

@Benoit, if you're using Heroku you probably don't want to worry about managing servers and scaling. In that case I recommend using Pusher. It's also listed on the Heroku Add-ons page.

Avatar

@Nate, I am guessing any other speed/memory differences would be minimal. After the methods are defined (happens when class is loaded) it should be quite fast. But I haven't done any benchmarks.

@MissingHandle, I don't know about decl_auth, but I hope to get support for this into CanCan 2.0. You can keep track of the issue here.

https://github.com/ryanb/cancan/issues/#issue/317

Avatar

Thanks guys for mentioning alternative solutions. I'll have to check those out.

@miguelsan, thanks! Code is added now.

@Prem, we can't use $(this) here because it is still the scope of the dom ready function. We don't have a new function, just a hash of options.

Avatar

@4ware, Paper Trail is only available for Active Record, there is mention of adding Mongoid support here: https://github.com/airblade/paper_trail/issues#issue/35

@Steve, I haven't tested this with associations yet, but try adding has_paper_trail to both models and see if it brings back the association. If that doesn't work, I know Vestal Versions has a ":tracking" option for this, so you may want to use that if you need this functionality.

@otagi, right, you would only want to add this where it works well.

@/users/1021, yes, but they can also edit other models by guessing their ids. If you are restricting permissions in the resource controller, you will also need to restrict them in the versions controller. You may want to use CanCan for this so the permissions are all in one place.

@Javi, thanks for the info. I didn't realize Vestal Versions allowed deleting of older records.

Avatar

@Amr, yes, CanCan will work with any authentication solution. It just relies on a current_user method, which even then you can customize.

@alex, thanks. I expect to.

Avatar

@Luke, you can certainly connect to any server running Beanstalkd, it's not necessary to do it all over the same server. However authentication is up to you.

@Sohan, I place the jobs in the config directory because it is very similar to deploy.rb for Capistrano. It requires an external dependency (stalk command) to run it and in a sense it is configuration for Stalker.

See my response to Nico above for how this compares to Delayed Job.

@Marquisdebad, Beanstalkd does have persistance with the "-b" command, however I prefer to use it in situations where persistence isn't necessary. That is where you can requeue anything based on the database.

Also authentication isn't a problem if Beanstalkd is running on the same server as your app. Just block external traffic to that port.

Beanstalkd is lightweight and fast. It is event driven which means it responds instantly to the jobs and doesn't do constant polling. I find that to be its biggest advantage.

@Yorick, I just switched to GitHub authentication for commenting here which should take care of the spam problem.