RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

I am trying to build a PoC (proof of concept) for 1-N relationship with Mongoid following this particular tutorial. I have built 'Blog' & 'Comment' controller. But everytime, I am trying to add a new comment I run into an exception.

More details, here http://stackoverflow.com/questions/23506752/mongoid-1-n-relationship-one-to-many-in-rails-4

can someone help me out? Thanks in advance.

And the source code is here Link
SP

Avatar

I forgot to include @entry.save, which became problematic in Part 2... modified create method below.

ruby
    def create
        @entry = Entry.new( entry_params )
        @entry.save
        respond_with @entry
    end
Avatar

Since the given EntriesController doesn't use strong parameters, I'd get 500 errors when attempting to create/update entries in the console. I revised EntriesController to the below version, which hasn't thrown any problems my way so far.

ruby
class EntriesController < ApplicationController
    respond_to :json

    def index
        respond_with Entry.all
    end

    def show
        respond_with Entry.find(params[:id])
    end

    def create
        @entry = Entry.new( entry_params )
        respond_with @entry
    end

    def update
        @entry = Entry.find(params[:id])
        respond_with @entry.update( entry_params )
    end

    def destroy
        respond_with Entry.destroy(params[:id])
    end

    private

    def entry_params
        params.require(:entry).permit(:name,:winner)
    end
end
Avatar

This helper should go down in the Rails Gallery of Art/Hall of Fame- It looks so simple, but there so much going on right in front of your face.... I have revisited it several time to remember all of the mechanisms. These patterns have helped me trim a lot ofugly out from my views. Thanks!!!

Avatar

I didn't see any documentation on how to tweak controllers. Where might I be able to find something like that? for instance, redirecting to a different route.

Avatar

It's solved by updating my Rails version 3.2.12 to 3.2.13

Avatar

I was thinking along the same lines. The logic is very simple. Set the guest field to false when updating the attributes within the update action. If it is the user's intent to become a full-fledged member, they will input the information required to submit the form to the update action. Bottom line, there are very few reasons to set the guest field to true again, thus setting the guest field to false on each update will easily circumvent the issue of converting users.

Avatar

Thanks Ryan and your team. This site is extremely help me to learn new things easy way in ROR. Recently I have started Testing using Cucumber and I tried to install it as you have described.

I am using Rails 3.2

ISSUE: when I try to run rake cucumber I am getting this error:-

"Rack::File headers parameter replaces cache_control after Rack 1.5.uninitialized constant SimpleForm (NameError)"

Can anyone please help me to resolve it? Thanks in advance... :)

Avatar

Thanks for this comment, really helped out.

Avatar

Thanks for another great tutorial Ryan! Works great with Rails 4.

For anyone that is interested, here's a slick way to replace the generic loading text with an animated gif.

Replace

coffeescript
$('.pagination').text("Fetching more products...")

with

coffeescript
$('.pagination').html("<img src='/assets/ajax-loader.gif' alt='Loading...' title='Loading...' />")

You can create and download your own loading animation here:
Link

You can add the downloaded gif to your images directory under assets. Rails knows to look there.

Avatar

Thanks so much! Bashing head against syntax then saw your comment.

Life saved.

Avatar

did you solve this error? thank you!

Avatar

Same problem with TypeError "can't convert nil into String" any solutions?

Avatar

A little late to this party, but yes, he does mentions this in the notes for "tagging" episode, along with autocomplete.

Avatar

I succesfully implemented a tag cloud in Ruby, from scratch. Excellent tutorial!

Now I would like to make my tag cloud more dynamic, so that it allows you to narrow down listings.

On my photoblog, each photo has several tags. Once you click on a tag, say "Tokyo", all photos tagged with "Tokyo" are listed. I now want to add two things:
* I want the tag cloud to be updated and display only tags associated to the remaining photos, the "Tokyo" subset.
* When you click on a tag in this subset-tag cloud, say "2008", I want all photos to be listed that are tagged with "Tokyo" and "2008" (instead of all photos tagged with "2008").

I have been trying to implement this for days, no luck so far. I'm new to Ruby so any help will be much appreciated!

Avatar

Quick note for anyone scouring these comments for updates:

Check out Sucker Punch https://github.com/brandonhilkert/sucker_punch for simple background jobs that can run within the same process as your app.

Avatar

dnewkerk, you are a champ. Thanks for you all your effort :)))))

Avatar

Amazing railscast. Don't think I've seen a clearer explanation of anything, ever! Thanks!

Avatar

I'm using rails 4 and i got this problem after i used this code i got this error in my browser

GET http://172.26.241.33:3000/galleries/2/comments 500 (Internal Server Error) jquery.js?body=1:9667
send jquery.js?body=1:9667
jQuery.extend.ajax jquery.js?body=1:9212
jQuery.(anonymous function) jquery.js?body=1:9358
CommentPoller.request comments.js?body=1:7

and as you see, rails included "/comments" into the url with i didn't expect it. It must be just "/galleries/2"

$('#comments').html("<%= j render(@comments) %>");
CommentPoller.poll();

I suspected it must be the 1st line that makes my project error, but i don't know how or why???

please help me out or do you have another tutorial for rails 4 please let me know.

Avatar

Ryan, even though there haven't been any Railscasts for a while, I keep referring back to these and they've saved me so many times. Thanks!

Hope all is going well on your hiatus.

Avatar

I figured it out.

First, change the target for your form (leave the "post" though).

<div id="upload_form">

  <%= s3_uploader_form post: user_url(@user), as: "user[avatar]" do %>
    <%= file_field_tag :file, multiple: false %>
  <% end %>

  <script id="template-upload" type="text/x-tmpl">
    <div class="upload">
      {%=o.name%}
      <div class="progress"><div class="bar" style="width: 0%"></div></div>
    </div>
  </script>

</div>

In the javascript file (I converted it from coffee script) change this line in the done callback:

$.post(to, content);

to

jQuery.ajax({
  type: "PUT",
  url: to,
  data: content
});
Avatar

Hi ano1chan

I am having the same Issue now , i am exporting excel files with large records , consuming my all memory, can you help ?

Avatar

Hi Ryan,

I tried to follow your paypal notification tutorial on screen cast but It didn't work for me. I'm currently using rails 4. However, Paypal basic work well. thanks in advance !

Avatar

Thank you! This was the easiest way to ensure that people couldn't use a brute force attack to find every user ID on my site.

Avatar

I had trouble getting the example code from GitHub running (ran into many of the issues mentioned throughout these comments). So I went ahead and created a new version of the Questionnaire app based on Rails 4 that implements strong parameters in the surveys controller in place of Rails 3 attr_accessible, and fixes the issue with Turbolinks. The rest is largely identical to the RailsCast example. Works great for me, though please feel free to submit issues or fixes if you'd like.

Working Rails 4 version:
https://github.com/dnewkerk/nested-model-form

If anyone happens to try out the Rails 4 example on iroller.ru mentioned a few comments above, note that I think the params aren't quite right in that example (log shows unpermitted parameters errors). You need to add :id as well as :_destroy to survey_params. Also you shouldn't need to add the questions controller.

Hope this helps!

Avatar

Prawn had support for 'templates' removed in recent versions. The only solution I know of is to put shared content into helper modules, then mix those modules into each class that you need them in.

I wrote a short example of how to do this here

Avatar

I've got the same problem (unicorn taking long time to compile assets in dev) and am using the rails-dev-tweaks gem, which still doesn't speed the compilation up...

Any other ideas?

Avatar

How to reprocess image for a style only i need?
Because i need manualy crop image for thumb4 and thumb6 ?

Model

ruby
class Post < ActiveRecord::Base
  
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h, :crop_style
  
  after_update :reprocess_image, :if => :cropping?

  has_attached_file :image, :styles => {
    :thumb1 => ["300x200#", :jpg],
    :thumb4 => { :geometry => "270x340#",  :processors => [:cropper]},
    :thumb5 => ["50x50#", :jpg],
    :thumb6 => { :geometry => "740x276#",  :processors => [:cropper]}
  }


  def cropping?
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
  end

  def image_geometry(style = :original)
    @geometry ||= {}
    @geometry[style] ||= Paperclip::Geometry.from_file(image.path(style))
  end

  private
    def reprocess_image
      image.assign(image)
      image.save
    end

end

Copper

ruby
module Paperclip
  class Cropper < Thumbnail
    def transformation_command
      if crop_command && crop_this_style?
        puts ">>>>> CROP THIS STYLE "
         crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ')
      elsif crop_command && !crop_this_style?
        puts ">>>>> NO CORP"
      else
        puts ">>>>> STANDART CROP"
        super
      end
    end

    def crop_command
      target = @attachment.instance
      if target.cropping?
        ["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"]
      end
    end

    def crop_this_style?
      @attachment.instance.crop_style.present? && (@attachment.options[:styles][@attachment.instance.crop_style.to_sym][:geometry].to_s == @target_geometry.to_s)
    end

  end
end

Slim template

ruby
- selected_style = params[:selected_style].to_sym

- content_for(:head) do
  = stylesheet_link_tag "jquery.Jcrop"
  = javascript_include_tag "jquery.Jcrop.min"
  javascript:
    $(function() {
      $('#cropbox').Jcrop({
        onChange: update_crop,
        onSelect: update_crop,
        setSelect: [0, 0, #{@post.image_geometry(selected_style).width}, #{@post.image_geometry(selected_style).height}],
        aspectRatio: #{@post.image_geometry(selected_style).width}/#{@post.image_geometry(selected_style).height}
      });
    });

    function update_crop(coords) {
      var rx = #{@post.image_geometry(selected_style).width}/coords.w;
      var ry = #{@post.image_geometry(selected_style).height}/coords.h;
      $('#preview').css({
        width: Math.round(rx * #{@post.image_geometry(:real).width}) + 'px',
        height: Math.round(ry * #{@post.image_geometry(:real).height}) + 'px',
        marginLeft: '-' + Math.round(rx * coords.x) + 'px',
        marginTop: '-' + Math.round(ry * coords.y) + 'px'
      });
      var ratio = #{@post.image_geometry(:original).width} / #{@post.image_geometry(:real).width};
      $("#crop_x").val(Math.round(coords.x * ratio));
      $("#crop_y").val(Math.round(coords.y * ratio));
      $("#crop_w").val(Math.round(coords.w * ratio));
      $("#crop_h").val(Math.round(coords.h * ratio));
    }


div style="width:#{@post.image_geometry(selected_style).width}px; height:#{@post.image_geometry(selected_style).height}px; overflow:hidden"
  = image_tag @post.image.url(:real), :id => "preview"

= image_tag @post.image.url(:real), :id => "cropbox"

= form_for @post, :url => admin_post_path(@post), :method => :put do |f|
  - for attribute in [:crop_x, :crop_y, :crop_w, :crop_h]
    = f.hidden_field attribute, :id => attribute
    br
  = f.hidden_field :crop_style, :value => selected_style
  p
    = f.submit
Avatar

http://stackoverflow.com/questions/23212898/tokeninput-not-load-the-existing-data-unless-reloading-page

I followed the railscast tutorial , but I found I can not load the "saved tokens".

I think the problem is that when click 'edit' link (created by scaffold),

it didn't trigger the preload function, how do you fix the problems in Rails 4

enter image description here

View page

  .form-inputs
    = f.input :name
    = f.input :content
    = f.text_field :user_tokens, data: {load: @article.users}

My coffeescript

$(document).ready -> 
  $('#article_user_tokens').tokenInput '/users.json',
    theme: 'facebook',
    prePopulate: $('#article_user_tokens').data('load')

Require the css and js file

 *= require token-input-facebook
 //= require jquery.tokeninput
Avatar

I am having the exact same issue. I think the reason is that the date field is not getting assigned the class that is needed for the JS to kick in.

I have no idea how to go about fixing this, but if I cannot find a way to do this then I will have to try going to a none dynamic way of adding a new nested record, as I will need the fields created with the correct class assigned to them.

Hopefully someone with more skill than myself can come up with a good solution for this.

Avatar

Ryan, thanks for the Railscast, very good and just what I needed. I seem to have this working with one issue. When I create a new nested record I have two fields that are using a datepicker class and then new records (I am guessing) don't have this class attached to them.

Would anyone know how to go about getting this fixed in a dynamic enough way? Would really like to get this working.

Many thanks.

Avatar

The #container div is in an erb template (/app/views/main/index.html.erb). The root route in /config/routes.rb points to the main controller's index action, which loads this erb template.

Avatar

How can the else case here would not fail, if we dont find and authentication with the provided params, and as there is no logged in user in this case so the current_user is Nil, so it should fail with Nil class exception when trying to call current_user.authentications.create(....)

ruby
def create
  omniauth = request.env["omniauth.auth"]
  authentication = Authentication.find_by_provder_and_uid(omniauth['provider'], omniauth['uid'])
  if authentication
    flash[:notice] = "Signed in successfully."
    sign_in_and_redirect(:user, authentication.user)
  else
    current_user.authentications.create(:provider => omniauth['provider'], :uid => omniauth['uid'])
    flash[:notice] = "Authentication successful."
    redirect_to authentications_url
  end
end
Avatar

Oh my god Thanks you saved my application :) I had issues with stack level too deep. I didn't know what to do with my RMagick. Thanks a lot!!!!

Avatar

Four years later I find this to be the most concise and most complete Getting Started with MongoMapper guide around! Thanks.

Avatar

I've implemented this, but the search seems to be case sensitive. I've tried to use the bCaseInsensitive = true in the js, but that doesn't change it. Not sure what in the datatables.rb is making it case sensitive. Appears to also be that datatables is case insensitive by default, so i'm guessing this code is overriding something.

thanks in advance.

jake

Avatar

I like to change the devise to es.yml
and
any idea on how to use my on layout view for the sign in

Avatar

If it's not too late: The GitHub page has a section "Whitelist" where it is explained how you can add third-party gems you want to exclude.

Avatar

You should be able to just include gem 'haml-rails' in your Gemfile now and have it work.

http://stackoverflow.com/questions/18485147/haml-rails-on-rails-4-0

Avatar

When I got to the 2 minute mark, at the page refresh, I got the following error: 'undefined method write_inheritable_attribute' for #<Class:0x007fccb5cd1c50>. Additionally it points to line 1:

ruby
1: <%- model_class = Factoid -%>
2: <div class="page-header">
3:   <h1><%=t '.title', :default => [:'helpers.titles.edit', 'Edit %{model}'], :model => model_class.model_name.human.titleize %></h1>
4: </div>

The Model:

ruby
class Factoid < ActiveRecord::Base
  attr_accessible :description, :name, :title, :tag_list

  acts_as_taggable

  validates_presence_of :description, :name, :title
  validates_uniqueness_of :title


  UNRANSACKABLE_ATTRIBUTES = ["id", "updated_at"]

  def self.ransackable_attributes auth_object = nil
    (column_names - UNRANSACKABLE_ATTRIBUTES) + _ransackers.keys
  end

end