RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

While it's fresh in my brain, here's an example for using the session.

Controller:

ruby
def new
  @search = SessionSearch.new(session)
end

def create
  @search = SessionSearch.create!(session, params[:search])
  redirect_to @search
end

def show
  @search = SearchSession.last
end

Model:

ruby
class SessionSearch
  class << self
    def create!(session, attrs = {})
      new(session, attrs).save!
    end
    
    def last(session)
      attrs = YAML.load(session['search_payload'])
      new(session, attrs)
    end
  end
  
  def initialize(session, attrs = {})
    @session = session
    @attrs = attrs
  end
  
  def save!
    @session['search_payload'] = YAML.dump(@attrs)
  end
end

There's probably ways to make this cleaner, but I think the idea is there.

Avatar

I agree with @Dom. Nothing wrong, just different use cases.

For the non-db backed, basic approach I'd make my route a singular resource

ruby
resource :search

The controller could just about stay the same, except for the show action:

ruby
def show
  @search = Search.last
end

And then the model could be something like:

ruby
class Search
  class << self
    def create!(attrs = {})
      new(attrs).save!
    end

    def last
      # retrieve the attrs from storage
      new(attrs)
    end
  end

  def initialize(attrs = {})
    @attrs = attrs
  end
  
  def keywords
    @attrs[:keywords]
  end

  def save!
    # store the attrs somewhere
    # maybe serialized in the session, or in mongo or memcached
  end
end

By "non-db backed" I mean you don't have to store every search, but you'd still need some type of storage. It's possible not to use storage by showing the search from the create action, but I think it's good practice to only display pages from a GET request.

Avatar

Impressive job! Keep up the good work :)

Avatar

Adolfo,

I had this same problem, but, my mistake. (i'm leaning Rails, lol)
On the "if else statements" in Rails 3 need to be:

ruby
respond_to do |format|
      if @user.save
        if params[:user][:avatar].blank?
          format.html { redirect_to @user, :notice => 'User was successfully created.' }
          format.json { render :json => @user, :status => :created, :location => @user }
        else
          format.html { render :action => "crop" }
        end
      else
        format.html { render :action => "new" }
        format.json { render :json => @user.errors, :status => :unprocessable_entity }
      end
    end

And not only just render :action => "crop".
I do not know if that was your problem, but it was mine...

Avatar

If you use

ruby
<%= best_in_class_if (logged_in? && post_owner?), @post, :title %>

Then it will render uneditable text if you don't satisfy the if statement.

Avatar

Is there any examples you can give of this working, I've integrated PJAX into my app and would really like fading transitions, I'm not that versed in js so examples of how to integrate this code would be awesome. Any help would be massively appreciated.

Avatar

The episode video doesn't work (always "Loading...") -- I've also tried to download the mp4 file but get a "404 Not Found"...

Avatar

pulpo did you figure out how to fix this on your local machine using mysql?

Avatar

One bug to watch out for is selecting a country and state, saving, and then changing it to a country that has no states. The old state will still persist on the object because the state select was emptied, so no value will be POSTed/PUT for state. You can either do .html($("<option>").attr('selected',true)) instead of empty() or you can have a hidden field with the same name, like Rails does for checkboxes.

Avatar

Great plugin, great screencast.

Any way to tab through the multiple fields (MS Excel style) and submit once the mouse clicks outside of the fields?

Do you think this can work for "complex forms" or "nested_forms"?

Avatar

@izumeroot: I had the same issue. Turns out, I had forgotten to do "rails g devise:install"

Avatar

Great screencast - great gem. However, there's one big problem with validation. It tells you what you did wrong, but it doesn't show you what you did. It's especially bad with the email example. The field contains a valid email. The user changes it to an invalid email. The valid email is redisplayed with a message saying it's invalid!

I think one of the prime directives of UI should be that if the user makes a mistake, he should be able to edit it, rather than re-enter it.

I can see some uses for this gem, but I would not use it if validation is needed.

Avatar

Is there any way to make sure that only if logged_in? and post_owner? conditions are satisfied before showing the editing area

Avatar

I haven't look into that but as far as I can tell it looks complicated to integrate.

Avatar

Hi @Gr, I agree you should use best in place only in the right places and when it makes sense. However the overload you might experience will be low since these requests do not render any content and will be served fast.

Anyway best in place is not meant to be used as an alternative to large forms, only for small and concrete things.

Avatar

It's impossible to edit a field with a blank value ;) At least in Ryan's Demo. Some styling might help?

Avatar

Hi, I would write the create method like this:

ruby
  def create
    @commentable = find_commentable
    instance_variable_set("@#{@commentable.class.to_s.downcase}", @commentable)
    comment = @commentable.comments.new(params[:comment])
    if comment.save
      redirect_to @commentable, :notice => "Comment successfully created!"
    else
      render "#{@commentable.class.to_s.tableize}/show"
    end
  end
Avatar

@gaaady: the on_the_spot gem offers similar functionality, but uses jEditable under the cover, so standard comes with the Ok/Cancel buttons and is form-builder agnostic, so usable from simple_form, formtastic, ...

Hope this helps.

Avatar

thanks Ryan, really good as usual.
Do you think it's complicate to replace the text_area
by ck_editor or some like that ?

Avatar

thanks for the screencast but i think we must use it carefully cause it sends much more request to the server than the usual form.

Avatar

Hi,
You can watch previous episode which is about Sorcery.

Cheers.

Avatar

I take it back, i figured it out.

Avatar

Thanks for the screencast
Does any one know if it can be integrated with simple_form ?
Is theere any easy way to add a submit and cancel buttons instead of hitting enter/esc ?

Avatar

Thanks Ryan, i have been looking for this. You are the best. How can one use this with tinymce or allow some HTML?

Avatar

Great video. I tried using this on my site but had no such luck.

I replaced Country and States to States and Cities.

I'm getting the error in my console "cities is not defined" any suggestions?

Thanks, Frank

Avatar

Hi,

I am using rails 3.1 and can not get the Update to actually delete the question when i click on the delete link.
The question is disappeared but the destroy command is not sent to the server and therefore when i refresh the page, the question reappears.

Anyone has any ideas?

thanks,
Liad

Avatar

Stupid question, but does anyone got any chance at removing images ?
Supposedly there is some way by adding a checkbox named :remove_image or whatever your image is called.

But it doesn't seem to work. Could someone help me ?
Thanks a lot!

Avatar

Ryan's suggested approach makes testing PDFs a breeze.

Create a new unit spec for the OrderPdf class and focus on the #render() method.

As a simple first step, spec that the render() methods returns a string that starts with "%PDF" to make sure it's generating a PDF.

To improve the specs, I'd check the PDF contains the appropriate text.

pdf    = OrderPdf.new
reader = PDF::Reader.new(StringIO.new(pdf.render))
page   = reader.page(1)

page.should include("order #1")
Avatar

Cool stuff, Ryan. I would change the end of your coffeescript a bit. It is more efficient to use chaining rather than select the #person_state_id element on back to back lines. Plus, I like that it is more concise. Like this:

javascript
if options
  $('#person_state_id').html(options).parent().show()
else
  $('#person_state_id').empty().parent().hide()
Avatar

url_for in Rails 3.0+ includes the :subdomain option, so you don't have to override the method any more.

Avatar

You could also use

$('#person_state_id').parent().toggle(options)

Avatar

Just for the sake of new visitors, Rails has changed quite a bit during the last 4 years. Here's how you could do it now:

application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery
  rescue_from Whatever::Exception, :with => :whatever_exception
  
  private
    def whatever_exception
      # do something here
    end
end

Here's some basic guide (official)

Avatar

So got it: The Installation of Imagemagick an RMagick was incorrect. Installed the actual Version of xcode, uninstalled imagemagick (had several 6.xx Versions around) and uninstalled rmagick. Installed everything new and did this:

brew remove imagemagick
rm -rf 'brew --cache imagemagick'
brew install -f imagemagick --disable-openmp

works fine.

Avatar

How would you incorporate this with a many to many association where you have a product and category and an association model with product_id and category_id?

Avatar

I had a big crash too. I used this configuration:

ImageMagick 6.6.7-0 2011-11-26
rmagick (2.13.1)

on rvm 1.8.5 Ruby Version: 1.9.2, Rails 3.1.1

Using rake (0.9.2.2)
Using multi_json (1.0.3)
Using activesupport (3.1.1)
Using builder (3.0.0)
Using i18n (0.6.0)
Using activemodel (3.1.1)
Using erubis (2.7.0)
Using rack (1.3.5)
Using rack-cache (1.1)
Using rack-mount (0.8.3)
Using rack-test (0.6.1)
Using hike (1.2.1)
Using tilt (1.3.3)
Using sprockets (2.0.3)
Using actionpack (3.1.1)
Using mime-types (1.17.2)
Using polyglot (0.3.3)
Using treetop (1.4.10)
Using mail (2.3.0)
Using actionmailer (3.1.1)
Using bcrypt-ruby (3.0.1)
Using orm_adapter (0.0.5)
Using warden (1.1.0)
Using devise (1.5.1)
Using fastercsv (1.5.4)
Using formtastic (1.2.4)
Using has_scope (0.5.1)
Using responders (0.6.4)
Using inherited_resources (1.2.2)
Using arel (2.2.1)
Using tzinfo (0.3.31)
Using activerecord (3.1.1)
Using activeresource (3.1.1)
Using bundler (1.0.21)
Using rack-ssl (1.3.2)
Using json (1.6.1)
Using rdoc (3.11)
Using thor (0.14.6)
Using railties (3.1.1)
Using rails (3.1.1)
Using kaminari (0.12.4)
Using polyamorous (0.5.0)
Using meta_search (1.1.1)
Using sass (3.1.10)
Using activeadmin (0.3.4)
Using ansi (1.4.1)
Using carrierwave (0.5.8)
Using coffee-script-source (1.1.3)
Using execjs (1.2.9)
Using coffee-script (2.2.0)
Using coffee-rails (3.1.1)
Installing jquery-rails (1.0.19)
Using rmagick (2.13.1)
Using sass-rails (3.1.5)
Using simple_form (1.5.2)
Using sqlite3 (1.3.4)
Using turn (0.8.3)
Using uglifier (1.1.0)

Avatar

Sorry new to rails/ruby this is all that's needed...

ruby
@user = User.new(params[:user])
def create
if params["format"] == "json"
    @user.password = [params[:password]]
end
#etc..
Avatar

I'm getting the same error here. I think you need to edit your app on dev.facebook.com and change the website: site_url so that facebook knows where to redirect back to. I haven't figured out what magic needs to be here to get it to work but I'll keep trying.

Got it! Edit your app > website > site url: http://0.0.0.0:3000/

This is working on my ubuntu box. You can figure out what url you need by looking at the url of the page that is giving you the error:

https://graph.facebook.com/oauth/authorize?response_type=code&client_id=141936272547391&redirect_uri=http%3A%2F%2F0.0.0.0%3A3000%2Fauth%2Ffacebook%2Fcallback&parse=query&scope=email%2Coffline_access

you can see that the redirect_uri = http://0.0.0.0:3000/

HTH - Andrew

Avatar

I'm creating an app to allow users to interact with all of their social networks. So, for my use case, I want users to authenticate with facebook, twitter, and linkedin. Anyway, that's why I need user to has_many :authentications.

Avatar

There is SOAPClient. It's very simple - not a near SoapUI in terms of features.
But it might be a plus for simple queries and testing. Was a god bless for me for some time. But as you go deeper there is no alternative SoapUI which is really a pain to use on Mac.

Avatar

And also there is SimpleWS lib: https://github.com/mikisvaz/simplews

Which is actually a wrap around Soap4r but much easier to get started.

Avatar

Great episode thank you Ryan, keep the good work ;-)

Avatar

Nice episode as usual, thanks a lot.

I'm wondering how to activate Mercury editor on the 'new' view.

I tried redirecting /pages/new to /editor/pages/new like this :

routes.rb
match "/pages/new" => redirect("/editor/pages/new")

but without success.

I'd like to keep the usual new_path, which is conventional.

Avatar

I have rails 3.0.3 and it seems impossible to make content.blank? work with both create a destroy. And i should add my nested element use paperclip.

Avatar

A revisited episode of this would be fantastic as well as a look at alternatives :)