RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

+1 for the OpenStruct. It really makes it rails way. I used to add value: hash['field'] to each dynamic field and that was evil ;)

Avatar

I am having a problem with the meta_request gem with dragonfly. When I upload an image I get a "closed stream" error. The upload completes though.

Avatar

Hi, I have configured everything as the ryan suggested, and better errors already creates a link such as this one:

subl://open?url=file://%2Fusr%2Flocal%2Frvm%2Fgems%2Fruby-1.9.3-p362%2Fgems%2Factionpack-3.2.11%2Flib%2Fabstract_controller%2Fbase.rb&line=116

But sublime text 2 ignores that link on Google Chrome with Windows 7. Can someone help? That subl-handler seems to be Mac OS realated only. What about people running Sublime Text 2 on Windows?

Thanks

Avatar

When I select the files or file, nothing happens.

I get the following error on page load:

TypeError: document.getElementById(...) is null
[Break On This Error]

return document.getElementById(id).innerHTML;

The id is: template-upload when I check it in Firefox.

Any thoughts?

Avatar

I ran into this issue after 5 deployments where the new master process would report a Gemfile not found (Bundler::GemfileNotFound) error and quit. It turn's out that the new master process was using a environment variable setting BUNDLE_GEMFILE which referred to a older release that has been cleaned up and no longer exists.

The only way to fix this at the time was to stop and start the unicorn process which defeat's the purpose of zero downtime deployment. To prevent this from happening in your unicorn config template add this block

ruby
before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "<%= current_path %>/Gemfile"
end

you do have to run unicorn:setup and maybe stop and start the service to make sure the new config setting is picked up.

Avatar

Yeah, I'm a little confused about the best method to go about this as well — I guess since update_attributes is deprecated in Master we should be checking attributes via assign and the saving if successful?

Avatar

Never mind. Got it to work. I was passing the wrong data into the validation.

Avatar

Is there a good way to prevent an user from adding (following) a friend more than once?

EDIT: This will do it:

ruby
<%= if 
    current_user.friendships.where(:friend_id => user.id).where(:user_id => current_user.id).empty? 
    link_to "Add Friend", friendships_path(:friend_id => user.id), :method => :post 
    end %>
Avatar

provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET']

This line of code will generate this error

(get { "error": { "message": "Missing client_id parameter.", "type": "OAuthException" } } )

for some versions of omniauth(i think from 1.0 + ). For this to work, change that line into:

provider :facebook, FACEBOOK_APP_ID, FACEBOOK_SECRET

Avatar

hi ryan what if i want to add facebook comments to my rails application, how do i go about it so i can add this comments too to my database

Avatar

In sessions_controller.rb

ruby
  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      ....
    else
      ....
      render "new"
    end
  end

the missing part is render "new"

Avatar

Great cast, interesting and well timed. Quick note that the products/show code is missing form the show notes. But I think we can handle that ourselves ;-)

Avatar

In case you would use Hstore (PostgreSQL) do you think it would be simpler and faster?

Avatar

Exactly what I needed, subscribed to gain access to the revised versions, first for Revised 88 and now this one. Thank you so much!

Avatar

I like the OpenStruct.new usage in this episode. This episode is really a very sharp. Thank you Ryan.

Avatar

I'm using the code introduced in this tutorial, and validation of the time_zone field fails with the error: Time zone is not included in the list.

ruby
#--- View ---
f.label :time_zone
f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones

#--- Model ---
validates_inclusion_of :time_zone, in: ActiveSupport::TimeZone.zones_map(&:name)

Has anyone else encountered this?

Avatar

After a lot of investigating I found a way to run validations on tags using something very close to Ryan's code.

I'll just put the code that I changed:

ruby
class Post < ActiveRecord::Base
  attr_accessible :content, :summary, :title, :tag_list, :tags

  # association code here...

  validates_associated :tag_list
  before_save :save_tags

  # validation code here...

  # other methods shown in original code...

  def tag_list
    caller[0][/`([^']*)'/, 1] == 'block in validate' ? @tag_list : tags.map(&:name).join(", ")
  end

  def tag_list=(names)
    @tag_list = names.split(",").map do |n|
      #self.tags.find_or_initialize_by_name(name: n.strip) #uncomment this if you want invalid tags to show in tag list
      Tag.find_or_initialize_by_name(name: n.strip)
    end
  end

  private

    def save_tags
      self.tags = Tag.transaction do
        @tag_list.each(&:save)
      end
    end
end

A little explanation: I found that adding Tag objects to @post.tags automatically validates, and I believe attempts to save, the Tag object. So if any Tag object is invalid, it's validation will run, and fail, when the array of Tag objects is set to the value of self.tags in the tag_list= method.

(The method used by the update method in the PostController to update the model, update_attributes, automatically saves the entry if it's valid by the way.)

So, we need a way then to validate the Tag objects when the post object is being validated. So what what we can do is store the array of Tag objects generated in the tag_list= method to an instance variable called, wait for it, '@tag_list'. By adding :tag_list to our list of attr_accessible items, we can then use validates_associated to run validations on @tag_list when the post object is validated.

Because we named the array @tag_list, errors will be returned as errors on the tag_list attribute that we access for our post form. Which is good.

If the post object successfully saves -- meaning everything, including the Tag objects, validated -- we use a before_save hook to save the array of Tag objects stored in the tag_list and update self.tags.

The only thing left to do was to update the tag_list method so that it returns the string of tags except when the method is being called by a validation method, in which case it returns the @tag_list array.

Avatar

Hi everyone, I'm trying this gem but I have different scenario. What I need this gem is for assign "points" for a "Employee" model, every-time when a "Manager" create "Job" entry. I have written a question on this on stackoverflow - appreciate if someone can help me out.

http://stackoverflow.com/questions/14556247/rails-reputation-system-for-a-content-management-system

Avatar

I agree... would love to see a version of this gallery has_many photos association

Avatar

CanCan + Devise = awesomeness.

Ryan, any chance of updating this episode?

Avatar

Same here... I can't work it out.

Avatar

Has anyone had success with multiple subdomains having separate sessions as per this question on stackoverflow? http://stackoverflow.com/questions/14573761/rails-separate-sessions-over-multiple-subdomains

Avatar

I noticed that you don't sanitize user input. I've also noticed that eleasticsearch is not very fond of several characters, like / [ { } : / \ " or '. There are probably others too.

Avatar

Whats the advantage of moving your schema into ruby?

I found Hstore invaluable when using STI, because ActiveRecord's column-proliferation approach is an ORM wart of the highest order but I didn't really want to go MongoDB just yet.

Avatar

I got it to work on 10.8.2 with no problems. You should try submitting an issue to their page. Good luck!

UPD: Did you follow their instructions?
> Unzip it, then launch it. Select SublHandler -> Preferences..., then set the path for the subl binary.

You might probably need to first do this http://www.sublimetext.com/docs/2/osx_command_line.html

Avatar
/config/recipes/base.rb
def template(from, to)
    erb = File.read(File.expand_path("../templates/#{from}"), __FILE__)
    put ERB.new(erb).result(binding), to
end

should be:

/config/recipes/base.rb
def template(from, to)
    erb = File.read(File.expand_path("../templates/#{from}", __FILE__))
    put ERB.new(erb).result(binding), to
end
Avatar

Since oauth2 1.1.0 with CSRF protection this code doesn't work. Could somebody point right direction how to apply state param in this provider and client example. thanks

Avatar

I can't get subl-handler to open, I get "SublHandler quite unexpectedly." On OS 10.7.5.

Avatar

It's local to the thread (which can serve multiple users) but it is not local to the session. So you absolutely can get 'cross talk' between sessions unless you run the before_filter AND set the timezone on every request (even requests for non-logged-in users)

Avatar

But Time.zone is NOT request local. So if you change the Time.zone for User1, User2 will have their timezone changed also if their request occurs later in the same thread.

Avatar

To use BetterError's file opening protocol links (subl://) with Sublime you will need https://github.com/asuth/subl-handler

Thanks Ryan for pointing at such an amazing tool!

It even points at the right line!

Avatar

If you store the fields in a serialized Hash like in this episode then there's no convenient way to select/sort by these values using ActiveRecord (but you could sort them in Ruby using Enumerable#sort_by. You should check out Hstore (episode #345).

Avatar

Nice tutorial.

Running into an issue trying to get this to work. Running Ubuntu 12.1 and can't seem to get rmagick to install due to some dependencies including one I have been searching for a solution on
libmysqlclient16

Any suggestions appreciated.

Thanks
Stuart

Avatar

I have the same problem, did you manage to work it out somehow? Thank you.

Petr

Avatar

I ran into an issue when using the ActiveRecord version of this... Specifically, after starting up the server and entering a bunch of search requests (and then doing a bunch of other things on the site,) I began to get a warning in the log complaining about my db connection not being closed properly. This error coincided with every search after that point in time.

I think this may be because the middleware is inserted prior to ActiveRecord::ConnectionAdapters::ConnectionManagement (which is responsible for opening and closing DB connections.) ???

So, I inserted the middleware after the ConnectionManagement class and it seems to be working now.

Avatar

Great episode Ryan, thanks. Knowing about /__better_errors eases Ajax requests debugging !

I made a bookmarklet to switch to the current app's /__better_errors page from your toolbar : https://github.com/czj/better_errors_bookmarklet

Avatar

I have small problem.

I'm using polymorphic on my Review model as reviewable. Where users can review other users and posts.

How will I make it possible to have an owner for each review. BY owner i mean a associated user. Because owner User and the reviews on User are crashing. All good method i can follow or ideas ?

Avatar

How would you select or sort by these dynamic values with activerecord?

Avatar

Nice cast. I actually had a need for this kind of relation but did it using an EAV style set up rather than serialised arrays.

Avatar

Hi,

I have a problem with this solution, with the search.
I quickly typing a few numbers into search field, then I get the error on the server-side:

[2013-01-28 13:59:30] ERROR Errno::ECONNRESET: Connection reset by peer
/home/lena/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:56:in eof?'
/home/lena/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:56:in
run'
/home/lena/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

Please help me...

Avatar

Great railscast! Great gems! Thank you so much.
I tried it right away. It doesn't work with ruby-1.8.*
Looking forward to using it in ruby-1.9.* projects.

Avatar

Gnome-only solution.

Too many mac-specific stuff everywhere in the Ruby world. Sad. But in this specific case it is the Chrome fault. It is actually unable to launch external editor in Linux.

Avatar

Just a note for anyone that gets this error:

/Developer/Code/{omitted}/initializers/better_errors.rb:1:in `<top (required)>': undefined method `editor=' for BetterErrors:Module (NoMethodError)

Make sure you put "binding_of_caller" AFTER "better_errors" if you want to use the editor= feature. It's been working fine for months without the initializer.