RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

This worked for me:

ruby
class Order 
...
def self.open_orders
    joins(:events).where("order_events.id IN (SELECT MAX(id) FROM order_events GROUP BY order_id) AND state = 'open'")
end
Avatar

Manners man.

Anyway if you want to process thumbnails using an EC2 instance, you can setup your own processing server using imgr or thumbd.

If you think setting up & maintaining a server purely for image processing is too much of a hassle, I suggest using external services like Blitline or thumbr.it. I've got a demo of Rails + Blitline working if you're interested.

Avatar

@navbarBackgroundHighlight: none; fails

I'm not up on my .less so trying to figure this one out - any insight into this would be great , just trying to eliminiate highlight state or better yet direct it at an image source

Avatar

+1. I always do auth from scratch. It's just too personal to your app to 'outsource'.

Avatar

It's almost like playing detective. Thanks for this video! I enjoy seeing how you scour the internals of Rails and your thought processes.

Avatar

In my case I had to "wrap" in a jQuery function for it to work in development:

js
jQuery(function($){
        $("#announcement_<%= j params[:id] %>.announcement").remove();
});

no idea why, but it worked and all tests are passing!

Avatar

So, I have a riddle for the experts out there. Not sure if anyone checks these comments often, but here goes.

I'm using this in a custom spree app, so there is some name spacing going on. But I was able to get almost everything to work, making the required changes for the spree namespace. But the hide.js.erb just isn't firing. It's rendering fine, I can see in the log, the extra strange part is this works in production, just not in development...??? Which means my last test, "page.should_not have_content("Hello World")" fails...

Avatar

A bit belated, but I just implemented this feature into a new app I am working on and was looking for how to download only records in the current view or in a query. +1 for your tip above. Thank you. It works! It works!

Avatar

How would you test the guest behaviour with RSpec/Capybara?

Avatar

Could you post the CSS for the menus? Or add to show notes?

Avatar

Thank you for the link to ActiveModel::Serializers! It is awesome. I've built the needed JSON outputs in 5 mins for our all entities.

Avatar

Use poltergeist headless browser driver. It is similar to webkit-capybara, but it is built on top of PhantomJS and easier to setup (no need of Xvfb virtual frame buffer) and place this code to your spec_helper.rb to speed up the tests and to fix the multiple threads issue:

ruby
  # specs/spec_helper.rb  

  # Small hack to force Selenium/Webkit tests to use single DB thread
  # and speed optimization
  # See http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/
  # and https://groups.google.com/forum/#!msg/ruby-capybara/JI6JrirL9gM/R6YiXj4gi_UJ
  class ActiveRecord::Base
    mattr_accessor :shared_connection
    @@shared_connection = nil

    def self.connection
      @@shared_connection || retrieve_connection
    end
  end

  # Forces all threads to share the same connection. This works on
  # Capybara because it starts the web server in a thread.
  ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

  Devise.stretches = 1
  Rails.logger.level = 4

Note: If you are using Spork, place the code to "Spork.each_run" block.

Edit: Ooops. Ryan created an episode about PhantomJS 3 weeks ago. And he encourages to use this hack too ;-)

Avatar

Unbelievable. I spent my entire Saturday watching your videos on testing. Something I knew I should be doing, but never really took the time to learn. This one brings it all together. Absolutely brilliant! Thank you!

Avatar

I'm having this same issue. Have these steps changed with the new Twitter API updates?

Avatar

in case someone had this issue - in the end I have Tomaž Zaman solution with the helper method modification as below:

ruby
def tag_cloud(tags, classes)
    max = 0
    tags.each do |t|
      if t.count.to_i > max
        max = t.count.to_i
      end 
    end
    tags.each do |tag|
      index = tag.count.to_f / max * (classes.size - 1)
      yield(tag, classes[index.round])
    end
  end 
Avatar

I used this code, and it works but only if there are few tags.

Problem is that count is not a number so
max = tags.sort_by(&:count).last
doesn't sort it properly when number of tags is more than 9 for specific post/article.

I will try to write function to find max properly unless anyone has an idea how to have it as a number in the first place..

Avatar

Like others who commented here I have been putting off learning js as long as possible. Rails is friendly, js is scary! But not anymore... Thanks Ryan! This really helped me. So much to learn still, but I have a lot more confidence now!

Avatar

I've done all the above, but for some reason when I launch Induction, there is no "postgres" adapter available for me to choose. I am only given the options of redis, mongodb, and sqlite. Would anyone have ideas as to why thats the case?

I have uninstalled the previous Postgres that came on my machine (Mac OS X 10.8.2) and am only using Postgres server provided by Postgres.app. After doing the PATH fix you outlined above, I can access Postgres via the Terminal, but for some reason can't seem to get Induction to use it. Any help would be greatly appreciated.

Thanks in advance.

Avatar

how can you make this work on mobile phones? is it even possible?

Avatar

The history feature isn't working for me. I've done exactly as the tutorial has done but I get the following error when I try accessing the old url after editing it to a new url:

"Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return"."

def show

@track = Track.find(params[:id])

if request.path != track_path(@track)
 redirect_to @track, status: :moved_permanently
end

@profileimg = @track.author.image_url(:thumb).to_s
if (@track.active != true) && (@track.author != current_user) 
  redirect_to tracks_url, alert: 'The track you were trying to view was not published yet (still in draft) and you are not the author.' 
else 
  @mission = @track.missions.order("position ASC")  
  @comment = @track.track_comments

  count_hits()    
  respond_to do |format|
    format.html #show.html.erb
    format.json { render json: @track }
  end
end
end
Avatar

Hi Martin,

I've followed your routing tip above and it seems to mostly work for me however "Routes to use if no tenant subdomain exists" is tripping up on the 'around_filter :scope_current_tenant' used in the application controller. If I comment that out, the routing works for no subdomain, but then subdomain stop working. Any ideas how to get around this?

Thanks
Ryan

Avatar

I think I see what he's saying. Completely remove the polymorphic association, User and MemberProfile have a simple has_one/belongs_to association, guests are stored in Users table as well, but they have no MemberProfile so the profile_id foreign key in Users is null for guests and we conditionally build a PORO for guests when a null profile_id is found.

Avatar

Yes, sorry I meant GuestProfile as a PORO, not MemberProfile, as Ryan states at around 13:40 in the railscast.

It sounds like he's suggesting there would be no AR association between GuestProfile and User, that there would be a null check on profile_id in the users table and if the value was null then the app would generate a PORO in memory to handle Guest related behaviors (validations, methods, etc). But how would that PORO be bound to the relevant User record?

Avatar

I dare you to handle errors on direct uploads to S3. Then, the nightmare begins.

Avatar

do you mean if the guest profile would only be a simple nullobject instead of a whole AR object with a table?

there should be some nice content
http://robots.thoughtbot.com/post/20907555103/rails-refactoring-example-introduce-null-object
https://www.destroyallsoftware.com/screencasts/catalog/how-and-why-to-avoid-nil

you could define a simple method

ruby
def active_profile
  profile or NullProfile.new
end

profile would be the normal association

Avatar

It's there to ensure that your test cases are independent: that they pass regardless of the order in which they are run.

Avatar

I too would be very interested in seeing how to tackle authorization on an index page where the user should only see a list of appropriate objects.

Do you have plans to make another video or perhaps just show some example code for how this might be done?

Avatar

They now work out of the box with bootstrap and simple-form if you use the simple-form plugin which supports bootstrap wrappers

gem 'simple_form', '2.0.4'
gem 'client_side_validations', '3.2.1'
gem 'client_side_validations-simple_form', '2.0.1'

The gems must go in this order

Avatar

I guess STI with a document database is also a very nice solution. You dont have any nuls in those types of databases and the data is more saved as 1 object instead of several rows.

Avatar

I am using this in conjunction with Postgres by using texticle. So far it seems to be working quite well.

Avatar

What is the way to use Sunspot/Solr with mutiple fields ?
It works fine with a simple form, as explained in the screencast.

Avatar

It really, really is. The only downsides I've seen are managing a lot of junk accounts from expired sessions and limiting DB load when migrating/deleting guest users.

Ryan covers a simple solution for guest deletion here, but if you were to implement something similar in production you'd probably want to limit it to guest accounts who's sessions had expired. This is definitely stuff you'd probably be best off running as a background process or worker.

Avatar

I love the fact you did this TDD from the start, and I hope all future episodes have at least some TDD element. As a beginner, this actually made this more approachable for me, I know its working if my tests (your tests really) are passing. This is my first time reading comments on one of your episodes and man people are hard on you! Railscasts is my favorite tutorial site by far.... I always come back here and learn something new every time. Keep up the great work!

Avatar

Awesome! With the help of this and http://railscasts.com/episodes/17-habtm-checkboxes-revised I was able to integrate this to work the way I wanted. Thanks Ryan.

Avatar

Great episode!

BTW: Where is the best place to test the current_user helper method from the ApplicationController (controller spec vs. view spec)?
I want to cover this part as well with specs but having problems to access this method.
Hmm...

Avatar

Excellent episode.I am able to upload single file with carrierwave.

But I got 403(Forbidden) error when I try to upload multiple files using jquery file upload.

When I try to upload single/multiple file I get alert box saying failed to upload and in console it says "Failed to load resource: the server responded with a status of 403 (Forbidden)" and "XMLHttpRequest cannot load https://xyz.s3.amazonaws.com/. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin."

What do I need to do to fix this?

Thank you

Avatar

I use quite STI and polymorphism liberally, because I have sets of classes with exactly the same columns. Even so I learned a lot from this episode. I especially like the way you discussed the trade-offs between different approaches. Often, the hardest part is knowing the best option. I end up coding it one way, hating it later then refactoring it to another way. This can waste weeks of time if the models are heavily used throughout the application.

I also really like your authentication from scratch. When AuthLogic went through it's unsupported period (Rails 3.0) I was really stuck and really came to value being in control of my core logic. Often we use huge gems because we need 10 lines of code from them, and spend more time figuring out how to wrangle them to fit our needs when coding from scratch is tiny, fast and takes less time (Devise).

Thanks. Yet another episode worth a year of my pro subscription.

Avatar

I think it would be better to make an app that is so compelling the user wants to join. Why have grumbly users that are only there because it is too much work to switch.

Avatar

Thanks @bdudney -- I had the same issue, I much prefer your second solution. Thanks for saving me some time.

Avatar

What minitest advanced features can't use if you don't use the minitest-rails gem?