RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

I'm trying to use Form Objects for something more complicated than what is in this railscast. I'm interacting with multiple models and in this case it doesn't make sense for me to move the validations from each model or to replicate them in the form object. I've tried using a validate do block and going through each object i'm creating, seeing if its valid? then adding the validation errors to the errors of the form, but I'm having a lot of trouble getting this to display properly. Has anyone else run into this issue?

Avatar

This will overwrite the configuration that is already have been written.

Avatar

Hello,
I had an application with rails 4 & rubyzip gem installed.
I have 3 tables - students, exams & results.

I followed this video http://railscasts.com/episodes/362-exporting-csv-and-excel

I'm able to download individual table csv files but not all 3 at a single click.

And I want to download all these 3 table csv files as a zip file with rubyzip or something else.

Please help me. I searched every end of google but didn't find an accurate result.

Avatar

Mohamed Sami there're 2 ways to pass your issue

just use collect instead of each

ruby
def load_imported_products
  spreadsheet = open_spreadsheet
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).collect do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]
    product = Product.find_by_id(row['id']) || Product.new
    product.attributes = row.to_hash.slice(*accessible_attributes)
    product
  end
end

try adding each product to an array, then just return it

ruby
def load_imported_products
  spreadsheet = open_spreadsheet
  header = spreadsheet.row(1)
  products = []
  (2..spreadsheet.last_row).collect do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]
    product = Product.find_by_id(row['id']) || Product.new
    product.attributes = row.to_hash.slice(*accessible_attributes)
    products << product
  end
  products
end
Avatar

Thank you very much for the cast. I've been having trouble with Entry.query(). It gives me an Server Internal Error 500 and does not return the query. If I replace the call with hardcoded list of entries it works. Anyone knows what might me going wrong? thank you

Avatar

It would be nice if Ryan can do a screencast on new elasticsearch-rails gem, tire seems to get retired nowadays.

Railscasts rocks!

Avatar

This doesn't work for controller specs :( Any ideas on how to get this working for controller specs?

Avatar

Great help Ryan! Since Ryan is creating new records with his upload, using POST from the INDEX page, has anyone got a PUT to work? I want to upload the file as a PUT/update after my record is created from the record's SHOW page. All my attempts still show "POST" in the logs when they fail. I have it working his way, but don't know what I'm missing this other way??

Avatar

Thanks to the help of the latest comments, I got it running again. However, paperclip apparently does not reprocess the original picture anymore (see e.g. https://github.com/thoughtbot/paperclip/issues/1055). This will break the functionality when cropping a second time, as your image is then cropped from the real original, but you're actually cropping a cropped one.

To solve this, you could display the "original" when cropping. However, this may result in very unhandy displays.. any hints on that? Passing in the :original in the styles-params in the model will break the image.

Avatar

Thanks! I am using Postgres and you were right, converting the arrays from message.to and message.from to strings or getting the first elements solves the issue.

Avatar

Maybe not relevant now, but I had the same problem and found the solution in my PostsController under update. I just needed to add :tag_list to the permitted parameters like so:

ruby
class PostsController < ApplicationController

def update
...
  if @post.update(params[:post].permit(:title, :text, :tag_list))
...

Hope it may help someone else in the future.

Avatar

The coffeescript in the episode didnt work for me (I was trying to have the grouped_collection_select in a nested form, not sure if that was part of the issue)

But in any case, this did work, hopefully it helps someone: (using different id tags as the ones in my project)

Note the main difference being how I called the filter action

ruby
jQuery ->
        items = $('#quantity_item_select').html()
        $('.supplier_select').change ->
                supplier = $('.supplier_select :selected').text()
                options = $(items).filter((index) ->
                  $(this).attr("label") is supplier)
                if options
                        $('#quantity_item_select').html(options)
Avatar

I have the same issue. This SO question might help. However I haven't been able to get it to work myself.

Avatar

I'm having the same issue. For some reason it seems that my new.js.erb file is not getting loaded. My new action in my controller does not have a respond_to block, although the create action does.

Why is it not loading?

Avatar

+1 for more on Spree. I am having trouble customizing the app. Specifically I am using spree_fancy gem but can not customize the color scheme :(

Avatar

Thank you Ryan for the example. I am trying to apply for nested Post-comments-reply but I am stacked. Is there any one who can help me. thanks

Avatar

I take it you are using Postgres? Likely your message is returning arrays for "to" and "from" and Postgres is throwing an error because it expects a string. Try message.to.to_s or message.from.first

Avatar

The answer is here: http://stackoverflow.com/questions/13996259/testing-error-pages-in-rails-with-rspec-capybara

ruby
# /config/environments/test.rb
consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
Avatar

Did you find a good way to do this? For example, using this episode, ActiveRecord::RecordNotFound errors ultimately redirect to the errors/404 view. However, I have the following in one of my tests (Item belongs_to List):

ruby
scenario "item cannot be created without a list" do
  visit new_item_path # @list is not created because it's not the proper nested path
  page.should have_content('Not Found')
  page.status_code.should be 404
end

However, the test fails with the following:

ruby
Failure/Error: visit new_item_path
ActiveRecord::RecordNotFound:
  Couldn't find List without an ID

So the controller is working properly in requiring a list, but the test fails because it doesn't take into account the custom exception handling which should send the user to the 404. Hmm...

Avatar

Why did you have to use self.due_at in the setter method, but not in the getter method?

Avatar

As I've just started with rails, I want to share what worked for me. I'm using ruby 2.0 and rails 4.1, it's 2014 and amazingly, this tutorial is still valid!! with the EXCEPTION of:

  1. <%= form_tag ... %> Tutorial code omitted the '='

  2. In the /config/initializers/load_config.rb:
    APP_CONFIG = YAML.load_file("#{Rails.root}/config/config.yml")[Rails.env]

  3. Use APP_CONFIG['paypal_secret']. Not APP_CONFIG[:paypal_secret]

Also, we're not able to test the paypal return parameters unless we put in on a server as paypal can't send back to localhost:3000

Hope this helps!

Avatar

It's still breaking thing with Rails 4.0.x.
When using %{path} in the redirect, Rails will escape all the slashes in the path, so that the route will no more be recognized.

I found this to be a valid fix:

ruby
match '*path', to: redirect{|params| "/#{I18n.default_locale}/#{params[:path]}"}, via: :all
Avatar

I can't get past the step where you create a new record using the email contents.

ruby
Mailman::Application.run do
  default do
    puts message.from
    puts message.to
    puts message.subject
    puts message.body # or body.decoded, both work
    # The above works, but the below fails.
    Email.create(to: message.to,
                 from: message.from,
                 subject: message.subject,
                 body: message.body.decoded)
  end
end

I get the error type_cast': can't cast Mail::AddressContainer to string.

Full stack trace here.

Avatar

I want to create an api for an android application, would doorkeeper be perfect for registration and authentication? generally what is the best way to build a secure api? I found so many tutorials but that makes really many doubts.

Avatar

I'm confused about a few things.

  • Will this work with Rails 4?

  • You specify require: false for the mailman gem because you don't want it loaded in Rails but as a separate process. Is this how mailman is meant to be used? No where on mailman's userguide does it mention this.

  • There is no script directory in Rails 4? Sure I can just create it, but I imagine there is a better place to put stuff like the mailman_server file?

Avatar

Hello Ryan, thanks for your excellent guide.

I had a column like reference_id in answers model. I want to make it unique through entire Survey.

answers model
validates :reference_id, uniqueness: { scope: :question_id }

It is applying only for questions but what to do if i want apply through the survey ?

Avatar

+1 I am looking forward to a feature complete cast following this one up!

Avatar

Not well documented at all, but I found an answer so I'll answer here because Google brought me here:

ActiveAdmin.register Post do

scope :posted_by_tom_cruise do
Post.posted_by("Tom Cruise")
end
...

Avatar

I wish someone had an answer for this

Avatar

We can even easily change the JavaScript to make the search ‘live’ so that the results automatically update with each keypress. Note that this is only a quick demo and isn’t the best way to do this. There are several jQuery plugins that you can use if you do something like this in a production app. To do this we’ll replace the JavaScript that we used to submit the form through AJAX with this.

Can someone explain why this isn't the best way to do this? And what jQuery plugins to look at?

I've added the jquery.observe_field.js plugin to add a delay but my search/sort is laggy on my production server.

Avatar

This will make it case insensitive

ruby
  def self.search(search)
    if search
      #case insensitive
      where(['LOWER(name) LIKE LOWER(?) ', "%#{search}%"])
    else
      where(nil)
    end
  end
Avatar

Hello, I'm new in rails and I spend 4 hours to get it work :)

My addidions to this tutorial code:

In user model add

ruby
attr_accessible :avatar, :crop_x, :crop_y, :crop_w, :crop_h

In my controller (I'm using device, so in application_controller.rb)

ruby
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_action :configure_devise_permitted_parameters, if: :devise_controller?

  protected

  def configure_devise_permitted_parameters
    registration_params = [:avatar, :name, :email, :password, :password_confirmation]
    update_params = [:avatar, :name, :email, :password, :password_confirmation, :crop_x, :crop_y, :crop_w, :crop_h]

    if params[:action] == 'update'
      devise_parameter_sanitizer.for(:account_update) { 
        |u| u.permit(update_params)
      }
    elsif params[:action] == 'create'
      devise_parameter_sanitizer.for(:sign_up) { 
        |u| u.permit(registration_params) 
      }
    end
  end

end

Replace reprocess_avatar method with this

ruby
def reprocess_avatar
  avatar.assign(avatar)
  avatar.save
end

And finally replace cropper.rb as said before on this thread

ruby
module Paperclip
  class Cropper < Thumbnail
    def transformation_command
      if crop_command
        crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"]
      else
        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
  end
end

May be it'll help somebody.

Avatar

Anybody managed to make this work for facebook? I'm getting an Invalid redirect_uri error in my production environment but works fine in dev
thx for your help

Avatar

You can only set one the recipient and owner on the actual column. Any other dat you want to store could be added in params:

@other_user.create_activity key: 'user.added_to_group', owner: current_user, params: { group_id: group.id }

You could also store multiple users_ids in an array in params to denote which users were added.

{ group_id: group.id, user_ids: [user_ids] })

Avatar

it's possible add more than one trackable to one activity?
i.e if i want something like [one user] add [other user] in [one group]
or [one user] add [user1 ... userx] in [one group]

Avatar

Thanks, @Xavar. I had been using the following:

ruby
raise ActionController::RoutingError

But because I wasn't calling .new('Not Found') on it, I was getting a 500 (missing arguments) instead of the expected 404. So as a lesson, you can use either of the following to trigger a 404:

ruby
raise ActiveRecord::RecordNotFound
# or
raise ActionController::RoutingError.new(:not_found)
Avatar
ruby
class ThingsController < ApplicationController
  def show
    @thing = Thing.find(:id)
    if @thing.user != current_user && @thing.is_private?
      raise ActiveRecord::RecordNotFound
    end
  end
end
Avatar

sudo apt-get install redis-server

Avatar

I'm sure this is simple, but I can't find a way to manually send someone to a 404 (using the middleware approach). For example, I want to "hide" private widgets if the widget author is not the current user:

ruby
class ThingsController < ApplicationController
  def show
    @thing = Thing.find(:id)
    if @thing.user != current_user && @thing.is_private?
      # What do I put here to fake a 404?
    end
  end
end

I tried render text: "Not found", status: 404 but that does exactly that, just renders the text instead of handling it through the errors controller. I also tried render status: 404, but that still shows the record (albeit with a 404 status in the web inspector).

Avatar

Since rails 4.0.1 it is not working anymore. Cause activerecord is doing a check which results in the following error: "ActiveRecord::RecordNotFound (Couldn't find all Tasks with IDs (2, 3, 1) (found 0 results, but was looking for 3)):"

I did opened a issue a github for it: https://github.com/rails/rails/issues/14272

Avatar

Not sure why the creator of this didn't post this, but here is a working version of this episode for Rails 4. https://github.com/nynj/angular-railscasts-rails4 A summary of the differences:
1. Add in strong parameters in the the entries controller
2. add in csrf-tokens in the coffeescript
3. keep jquery in application.js. Not sure why this is needed, but I had to keep jquery in.

Avatar

Great explanation… very helpful! Thanks Justin. Also, I assume you meant allowed vs allow "is either true or is a block or is nil."

Avatar

undefined method `valid?' for 2:Fixnum

I'm getting this error blocked in here, do you have any suggestion, i'm using rails 4

def save
if imported_departments.map(&:valid?).all?
imported_departments.each(&:save!)
true
else

Avatar

Excellent. Just like a twist in a good fiction.