RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar
ruby
Controller:
def import
    Blog.import(params[:file])
    redirect_to blogs_path, notice: "Blogs importiert!"
 end

Model:

def self.import(file)
    allowed_attributes = [ "id","url","price_ek","price_new","si", "pr", "status" "updated_at"]
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      blog = Blog.find_by_id(row["id"]) || new
      blog.attributes = row.to_hash.select { |k,v| allowed_attributes.include? k }
      blog.save!
    end
  end


  def self.open_spreadsheet(file)
    case File.extname(file.original_filename)
    when ".csv" then Roo::Csv.new(file.path)
    when ".xls" then Roo::Excel.new(file.path)
    when ".xlsx" then Roo::Excelx.new(file.path)
    else raise "Unknown file type: #{file.original_filename}"
    end
  end

I used this Code for Rails 4 and it is creating the rows in the DB, but all values (url, pr, etc) are nil. Any suggestions what I have done wrong?

Avatar

Took too long to edit to correct my mistake. The code in the form above only works when the moved item is moved up. This is the hastily corrected version which is in need of some refactoring:

ruby
  def sort
    ids = params[:faq].map { |id| id.to_i }
    originals = original_ids(ids)
    moved = moved_id(ids, originals)
    item = Faqs.find(moved)
    item.insert_at(moved_to(ids,item)) # Using acts_as_list
  end

  protected

  def moved_id ids, originals
    offset = first_changed_index(ids)
    new_candidate = ids[offset]
    old_candidate = originals[offset]
    new_delta = (ids.index(new_candidate) - originals.index(new_candidate)).abs
    old_delta = (ids.index(old_candidate) - originals.index(old_candidate)).abs
    new_delta > old_delta ? new_candidate : old_candidate
  end

  def first_changed_index ids
    ids.each_with_index do |id, i|
      return i if original_ids[i] != id
    end
  end

  def moved_to ids, item
    ids.index(item.id) + 1
  end

  def original_ids ids
    Faq.where(id: ids).order(:position).pluck(:id)
  end
Avatar

It is actually possible to do all updates in a single query, preferably using the fact that your model is using acts_as_list:

ruby
def sort
  ids = params[:faq].map { |id| id.to_i }
  item = first_moved_item(ids)
  item.insert_at(moved_to(ids,item)) # Using acts_as_list
end

def first_moved_item ids
  ids.each_with_index do |id, i|
    return Faq.find(originals[i]) if originals[i] != id
  end
end

def moved_to ids, item
  ids.index(item.id) + 1
end

def originals
  @originals ||= Faq.where(id: params[:faq]).order(:position).pluck(:id)
end

This makes use of the fact that the insert_at method already has the logic to optimally execute the move in the most efficient fashion. For me this is more than an order of magnitude faster since I was using sorted on a list that could contain upwards of 500 items.

Avatar

Is there any way to create custom workflows for each user? So a user may design his own workflow, and an object goes through the states.

Avatar

I am getting an undefined method 'link_to_function' for in my views/surveys/_question_fields.html.erb at this line.

ruby
<%= link_to_remove_fields "remove", f %><br />

Here is the application_helper.rb

ruby
def link_to_remove_fields(name, f)
  f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end
Avatar

The figaro solution is cleanest, a single source of authority, hides everything from being exposed on remote repositories, and IMO is easier than secrets.yml in rails 4. Figaro is the way to go.

Avatar

Did you ever figure this out? I'm looking to do the same thing.

Avatar

Can we put code in products.js.coffee / home.js.coffee to application.js? so there will be less file in the folder and those files won't be necessary?

Avatar

As a group that has put together a production level Angular on Rails app, I was wondering if you could answer a question. For your app, do you have all your logic processed client-side (the Angular way) or do you additionally have endpoints that handle logic server-side in a more traditional Rails manner?

For example, going to "root/entries" accesses the Angular framework but "root/" or "root/users" work via logic initialized in a Rails controller and processed via ERB/HAML.

If the latter, how do you go about setting up the app for this type of behavior?

Avatar

Just a follow up on the issue with before_filter - if we set the time zone using before_filter at the top of the ApplicationController then why should bother about leaking it through to the whole process? Every new request to our application will go through the controller and for each new request the proper time zone should be set again right? We just need to make sure that it's always set and fallbacks to some default. Workers can handle time zone in a different way.

Avatar

I think it goes something like this
match : current_cart, to: 'cart', :controller => 'carts', :action => 'show', :id => 'current'

Avatar

One thing that isn't clear is this: Does a User have to authenticate with Twitter (through, like OmniAuth), or can they just authorize an app with read | read/write access?

Avatar

but when we run the "rails g integration_test task" command it automatically generates the spec/requests folder so how to change it to spec/features folder? Please help

Avatar

I guess the &crarr; that has snuck into some of the ASCIICast is just a line break/continuation indicator? You can dump the entity and rejoin the lines.

Avatar

You have to make sure in your model, you don't specify "counter_cache: true" when you're running your migrations. Otherwise, it throws "marked as read only" errors. It also does this when rolling back. So take note. I haven't been able to find a way around this. It seems you have to remove "counter_cache: true" when rolling back or migrating through a migration with counter_cache.

Wasted too much time just for a simple migration -_-

Also for rails 4, the syntax should be

Project.reset_column_information
Project.find_each.each do |p|
Project.update_attribute :tasks_count, p.tasks.length
end

update_counters, reset_counters, are all deprecated.
Note that the arguments syntax is different.

find_each is preferable because it executes in batches, not all at once.

Avatar

Late reply, but...

There's json.cache!, but I couldn't get that to work. I ended up doing a Rails.cache.fetch([id, 'name']) do ... end block around the entire json response in the jbuilder file.

Avatar

Yes...Angular it is!!! Congratulations Ryan

Avatar

Yes exactly...Even I think they aren't that grumbly..

Avatar

Oh yes...Even I was thinking on the same lines!!!

Avatar

This was an excellent lesson, which I implemented immediately. I had some trouble with the .css file, probably because it was a little weird to start. I had to delete the '.prettify' stuff. Here is what worked for me.

th a.current {
padding-right: 20px;
background-repeat: no-repeat;
background-position: right center;
}

th a.current.asc {
background-image: url(images/up_arrow.gif);
}

th a.current.desc {
background-image: url(images/down_arrow.gif);

Avatar

If at 2:45 when Ryan interacts with Twitter methods in the console you receive an "Unable to verify your credentials" error, see this Stack Overflow thread:

http://stackoverflow.com/questions/17719358/twittererrorforbidden-unable-to-verify-your-credentials/17726689#17726689

Steps involve copying and pasting the Twitter.configure block mentioned in the thread into omniauth.rb, then supplying config.oauth_token and config.oauth_token_secret with values from dev.twitter.com.

This is done by generating access tokens. I did this by visiting the Twitter app I created, clicking on the "API Keys" tab, then generating the access tokens at the bottom of the page. Doing so will supply you with values that you can plug into the Twitter.configure block mentioned above.

Avatar

Why just put the link stuff in the admin? Condition inside the js.erb partial ? Would be better than the display none :/

Avatar

That's one possible reason, but alas there are others...

Avatar

Anyone find a solution finally? I thought it was to pass signed_request params manually but that didn't work for me. Wrote a huge question about this here in case anyone can help: http://stackoverflow.com/questions/25819058/facebook-noauthorizationerror-after-passing-signed-parameters-manually

Avatar

hey, if you have a second, could you help me out on how you got it just to show a week?

Avatar

I would like to know if anyone has ever implemented their own registration/login system like what Ryan demonstrates here, and also include OmniAuth for authorizing external APIs like Facebook, etc.?

I have a specification that requires the user to register/login through our system, but they still need external API authorization(account access, data sharing, etc.) this means that even though they can tie in social media account and share information back and forth, they can't use an external API to register for our site. Does anyone have any suggestions? I guess my first question is - is what we need to do compatible with what OmniAuth allows?

Avatar

I am having the same error. Have you fixed it?

Avatar

I config server:localhost:9292/faye, run "rackup private_pub.ru -s thin -E production", it work very well, but i upload to my host, i change server:ip_mydomain:9292/faye then run "rackup private_pub.ru -s thin -E production" it not working...
i think Listenning: 0.0.0.0:9292 make it not working?
How to change 0.0.0.0:9292 -> ip_domain:9292?
Thank you very much!

Avatar

When I try to sign up through the user/new.html.erb form, I get a "can't leave password blank error" , I'm putting in a password every time. Anyone know what the problem is?

Avatar

You raise an interesting point about the performance hit from using cookies. From YUI's results it seems that only cookies larger 500 bytes really slow down the response time. Surely the increase in performance from page caching would outweigh the effect of slightly larger cookies. Though I agree that the increased complexity would be nice to avoid.

Avatar

It's good enough, but if you have a real project and don't want to waste a lot of time to setup test environment, you can try https://teatro.io

Avatar

If you need to setup test stages for testing concrete features, you can try https://teatro.io – it provides personal stage server for each feature

Avatar

Not sure if this is still applicable to you, but I ran into a similar problem and was solved by adding the following code in spec_helper.rb:

Rspec.configure do |config|
config.include Rails.application.routes.url_helpers
...
end

This allows named routes to work in rspec.

Avatar

I had a similar issue. I got it all stood up but had an index error.

I had to do something like:

rake environment tire:import CLASS='Article'

to re-index (or just index for the first time) everything in the db.

Avatar

Those trying to do this in modern-times:

I found that you need to make sure your multi_json gem is version 1.7.8 or earlier.

Avatar

Warning! ActionController::Live works badly with Redis, because Redis' subscribe function hangs the process and the stream never closes. More information: https://github.com/rails/rails/issues/10989