RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

InvalidByteSequenceError using pdfkit jruby 1.6.7-2

Avatar

sorry Dom
period at the last has gone out the link.
plz consider period at the last.

Thank You.

Avatar

Just saw that you're using rbenv. I have been thinking of switching from rvm for a while now, but a Railscast on the subject would definitely get me to actually do it. Please do one!

Avatar

Right now, there's no way to customize controller behaviour specifically, but there's a branch which will allow you to do this.

There's also a pull request related to application customization (ownership). Feel free to comment on that, we need ideas :)

Avatar

OAuth 2 is very strange at first sight. It was for me :-)

But, in the OAuth 2 spec site there's few diagrams that might help you, or check out the applications examples, like this one

Avatar

Excellent screencast as usual. I don't seem to be able to find any documentation though on customising the controllers Or models. Mainly things like having the applications associated to a specific user etc.

Avatar

Great screencast! One question, I keep getting exception notifications for the default_ignore_exceptions, why is this? Has anyone experienced this problem?

Avatar

This is difficult to grasp when we don't know the big picture. Diagrams are required to introduce the concepts before jumping into code. Also including specs with the code would be helpful.

Avatar

The gem was updated with the fix for whitelist_attributes. Check out the version 0.3.4

Avatar

For this I'd recommend looking into using the password grant type which doesn't require setting a callback URL.

Avatar

Awesome Ryan! Great job. I have one question. Let's say your client app is a mobile app (such as an android app), would you have to redirect to a browser (out of the app) when trying to login? The json part is ok as both android and ios have libraries for those.

+100 on this episode.

Avatar

Yes I have the same issue, although everything is working fine and it does not appear to be affecting anything (to my knowledge). Just an annoying message hopefully...

Avatar

My linode had to get restarted yesterday and I noticed that while the nginx service started properly, the unicorn socket didn't come back. I wonder how the deployment needs to be tweaked for events where the server has to get restarted. I assume it's a matter of running bundle exec unicorn on server startup.

Avatar

How do you autocomple the "restrict_access". It looked like it cycled through a few options...

Avatar

Kevin, the last time i checked, AMI for eu-west-1 for Ubuntu 12.04 LTS 64 bit is ami-e1e8d395 and 32 bit is ami-e7e8d393 :)

Avatar

AMI code for a kind of Image is different in each region, for example:

Ubuntu 12.04 LTS

Singapore:
64 bit: ami-a4ca8df6, 32 bit: ami-a6ca8df4

Northern Virginia:
64 bit: ami-a29943cb, 32 bit: ami-ac9943c5

I got the codes when i try to launch a new instance from AWS console and copy it. But maybe there's a better way to get it :)

Avatar

Ryan, can you make a tutorial for using "TOTP: Time-Based One-Time Password Algorithm" or "Multi-Factor Authentication" that compatible with Google Authenticator like in Google and AWS?? it will be great to add more security :)

Avatar

@Bardwin

Your example works very well. Thank you!

How to show a notice like "no record match" when there is no match record according to the input value?

Avatar

Is it possible to have a progress meeter like the jquery one you linked to?

Avatar

+1 on Derby. Derby allows you to use the 10k existing NPM modules vs the ~9 meteor only ones.

Avatar

I would love to understand this but my ruby skills are lacking. Can anyone point me to some good 1.9.2 resources?

Avatar

Have anyone tried using grape? It's built directly on top of Rack, which would seem to make it quite efficient. I think it also has an interface for oauth authentication.

Avatar

Make a generic api controller and inherit from that. Then override whatever you need to in the subclasses.

Avatar

I don't think that would be good practice. Some questions:

  • What about route path translation?

  • Why would you need a parameterized route when you won't be adding new models in runtime? It's just 3 cases, not infinite associations.

Lastly, this could potentially clash with other routes in your routes.rb file depending on your routes order.

Avatar

Alain, to me and in this case, being verbose is a feature, not a bug. Back to your example, I don't think a commentable_id really belongs to the controller. Most of my other comments apply to your code too.

Avatar

Interesting. However, the date part of the hash will probably leave you open for re-play attacks.

Avatar

There is also derby, a very similar framework with somewhat different philosophies. A Railscast on that also comparing it to Meteor would be great. From what I read, derby seems to be more flexible and less "lockin" then meteor.

Avatar

Why not just use a route like this?

ruby
get ':commentable_type/:id/comments', as: :comments
get ':commentable_type/:id/comments/new', as: :new_comment
Avatar

Holy crap, why have I not been using this!

Avatar

thanks a lot for this, was pulling out my hair over it!

Avatar

I have to agree that this cast was timed correctly for me as i was looking into something that could benefit from a polymorphic relation.
the other thing which i found useful is this code from stackoverflow, which shows how to set up a has many through polymorphic table

ruby
class Widget < ActiveRecord::Base
  has_many :widget_groupings

  has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person'
  has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien'
end

It looks like a great way to link locales to items for me

Avatar

Hey Alan,

you just saved my day! Thank your for pointing out the //= require_tree . issue. After I put in at the end of the application.js file everything started working.

Thanks again!

Avatar

hi, is there any way to encrypt on the way out / decrypt on the way in? i have sensitive info in my app that i'd like to ensure remains inaccessible to anyone who may connect to my memcache server.

Avatar

With the "server side solution" you can just pass your extra params through the path helper like this and the autocomplete jquery plugin will append them to the Ajax request:

_form.html.erb

ruby
<%= f.text_field :category_name, data: {autocomplete_source: categories_path(your_extra_param: 'value')} %>
Avatar

Great screencast. It helped me to DRY this problem a little bit up for SIMPLE model constellations as mentioned in this screencast.

Enclosed you'll just find an untested refactoring version but an older similar refactoring version has been tested successfully ;-)

So I would generally transform all tags with a data-autocomplete-source attribute into an autocomplete input.

application.js.coffee

ruby
jQuery ->
  $('[data-autocomplete-source*="auto"]').each (k, v) ->
    $(v).autocomplete
      source: $(v).attr('data-autocomplete-source')

This autocomplete data source can be put in a separate generic autocomplete action instead of the index action and be introduced to the client through a view helper:

application_helper.erb

ruby
module ApplicationHelper
  def autocomplete_input(f, field)
    f.input "#{field}_name", data: {autocomplete_source: eval("autocomplete_#{field.to_s.tableize}_path")}
  end
end

_form.html.erb

ruby
<%= autocomplete_input(f, :category) %>

routes.rb

ruby
resources :categories do
  collection do 
    get :autocomplete
  end
end

This module about a generic autocomplete action can be included at the top of every resource controller based on a ActiveRecord::Base child class (you have to set the autocomplete route for each controller as shown above):

ruby
module AutocompleteAction
  extend ActiveSupport::Concern
  
  def autocomplete
    render json: (
      request.path.split('/')[1, 2].first.classify.constantize.
      select(:name).order(:name).where("name LIKE ?", "%#{params[:term]}%").
      map(&:name)
    )
  end
end

The association setters could be generated dynamically through meta programming.

So the following code generates special setter methods for all belongs_to and polymorphic associations when included in an ActiveRecord::Base child class.

ruby
module AssociationSetter
  extend ActiveSupport::Concern

  included do              
    columns.map(&:name).select{|c| c.match('_id')}.each do |column|
      association = column.split('_id').first.classify
      
      define_method "#{association.underscore}_name" do
        self.send(association.underscore).try(:name)
      end
      
      accessible_attributes << "#{association.underscore}_name"
      
      define_method "#{association.underscore}_name=" do |name|
        return if name.blank?
        
        association_type = association
        
        if self.class.columns.map(&:name).include?("#{association.underscore}_type")
          association_type = self.send("#{association.underscore}_type")
        end
        
        self.send("#{association.underscore}=", association_type.constantize.find_or_initialize_by_name(name))
      end
    end
  end
end

P.S.: Maybe it turns out to be worth to extract in a gem some day ;-)

Avatar

An update to this railscast to help write better cucumber scripts would be a welcome step forward.

Avatar

Maybe a silly question but why the jquery-rails gem is not in the assets group?

Avatar

Just put :comment_type => :article, or :events, :photo in the routes as a parameter inside of the resources block and then setup a before filter to classify that value (params[:comment_type]).

Avatar

I'm using delayed_job (Rails 3.1) on Heroku. It seems to stall a lot, and can be tricky to start workers. I'm constantly paranoid that delayed_job may have fallen asleep and jobs are piling up in the queue (this happens pretty often, actually). Anyone know of any good resources for getting delayed_job to work reliably on Heroku? I installed the 'daemons' gem, but I generally just run "heroku rake jobs: work" to get things going again.

I'm sure I'm just doing it wrong, but I can't find too much out there to help me get everything set up to run efficiently.

Suggestions?

Avatar

I went ahead and started a project with meteor then got stuck on a multi-table-join problem.

I documented it here:
https://github.com/meteor/meteor/issues/147

For mainly this reason, I don't think meteor is production ready, but it certainly has some good ideas.

Avatar

I think, I have the same problem as Eran Kampf

Products.all when called from LocationsController::Location
=> MONGODB (0ms) db_development['products'].find({:_id=>BSON::ObjectId('4fb93d02c34cb976d5000004')}).limit(-1).sort([[:_id, :asc]])

Products.all when called from Api::V1::LocationsController::Location
=> MONGODB (0ms) db_development['products'].find({:_id=>BSON::ObjectId('4fb93d02c34cb976d5000004'), :_type=>{"$in"=>["Api::V1::ProductsController::Products"]}}).limit(-1).sort([[:_id, :asc]])

How to convert / remove "Api::V1::ProductsController::Products" ?

Avatar

Adrian: look at the solution I describe above. Way less verbose than yours and more flexible.

Avatar

I think it's a little confusing that you're showing two forms; a user registration form and than two extra steps in a separate form, while really all three steps could go in one form, making it a lot more sustainable.

More important I was wondering how Wicked handles file uploads?

Avatar

Is there a way this can be implemented where you only define new functionality in new versions? Say for example:

I have a Users controller and a Products controller. Products has stayed the same between V1 and V2, but Users has changed. It would be nice if we could set it up so that if I call for V2 of Products, my application knows it doesn't exist and simply uses the most recent controller version instead (in this case, V1).