Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
kayakyakr
Feb 16, 2004

Kayak is true

Jam2 posted:

I've designed some simple Ruby objects to model a problem and I like the way they're composed. I'd like to use them as the backend for a Rails app and persist the data to a database. How can I integrate this design into rails without having to make these classes inherit from ActiveRecordBase and tangle them together with the RailsWay of doing associations? Is that really the way to go? Ideally, I'd like to integrate this in a way such that the objects, at most, have some other object that they persist themselves to. I don't want to uglify this with Rails code. HALP!

code:
class Entity
  attr_accessor :description
  def initialize description
    @description = description
  end
end
code:
require 'interval'

class Group
  attr_reader :expenses
  attr_reader :memberships

  def initialize
    @expenses = []
    @memberships = []
  end

  def add_transaction e
    @expenses << e
  end

  def add_membership p
    @memberships << p
  end

  def balances
    Hash.new(0).tap do |balance_hash|
      expenses.each do |e|
        summ = 0
        rms = responsible_memberships(e)
        rms.each do |rp|
          summ += e.interval.overlapped_by rp.interval
          balance_hash[rp] = e.amount * summ / rms.size
        end
      end
    end
  end

  private
  def responsible_memberships e
    Array.new.tap do |rms|
      memberships.each do |p|
        fraction = e.interval.overlapped_by p.interval
        if fraction > 0
          rms << p
        end
      end
    end
  end
end
code:
class Interval
  attr_accessor :finish # because 'end' is reserved
  attr_accessor :start

  # initialize with two Ruby Time objects
  def initialize start, finish
    @start = start
    @finish = finish
    raise ArgumentError.new("invalid range") if (finish - start) < 0
  end

  # returns a float in range [0, 1] denoting the fraction overlapped by |other|
  # FIXME make sense of the math => make it pretty => make it fast
  # TODO careful with edge case where other start == this finish 
  def overlapped_by other
    return 1 if other.start <= start and other.finish >= finish
    return 0 if other.start > finish or other.finish < start
    num_secs_within_interval = (other.start - start)
    if other.finish < finish
      num_secs_within_interval = num_secs_within_interval - (finish - other.finish)
    end
    return num_secs_within_interval / dur
  end

  private
  # duration: the number of seconds (as float) elapsed within an interval
  def dur
    finish.to_f - start.to_f
  end
end
code:
class Membership
  attr_accessor :entity
  attr_accessor :interval

  def initialize entity, interval
    @entity = entity
    @interval = interval
  end
end
code:
class Transaction
  attr_accessor :amount 
  attr_accessor :description
  attr_accessor :interval

  # initialize with a float |amount| and instance of Interval
  def initialize amount, interval, opts = {}
    @amount = amount # currently float, TODO implement Money
    @description = opts[:description] if opts[:description]
    @interval = interval
  end
end

You could mongoid it?

Adbot
ADBOT LOVES YOU

Jam2
Jan 15, 2008

With Energy For Mayhem
I'm hesitant to use MongoDB to persist such relational data. It seems better to use a RDBMS. Thoughts?

I'm taking cues from Objects on Rails, but it hasn't become clear yet how to move forward.

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

Jam2 posted:

I've designed some simple Ruby objects to model a problem and I like the way they're composed. I'd like to use them as the backend for a Rails app and persist the data to a database. How can I integrate this design into rails without having to make these classes inherit from ActiveRecordBase and tangle them together with the RailsWay of doing associations? Is that really the way to go? Ideally, I'd like to integrate this in a way such that the objects, at most, have some other object that they persist themselves to. I don't want to uglify this with Rails code. HALP!

code:
class Entity
  attr_accessor :description
  def initialize description
    @description = description
  end
end

So, for example, an Entity instance would automatically persist itself on entity.description = "lol inner database pattern"?

Jam2
Jan 15, 2008

With Energy For Mayhem

Cocoa Crispies posted:

So, for example, an Entity instance would automatically persist itself on entity.description = "lol inner database pattern"?

I don't understand what you're saying to me.

KoRMaK
Jul 31, 2012



I'm still trying to make my own scaffold generator. For some reason, it cannot find active_record. I have no idea whats going wrong, I've been at this for a couple days. I monkey patched the scaffold_generator and it worked fine. Now I am trying to refactor that to a separate comand so we can scaffold for two different things (generate scaffold MyTest vs generate scaffold_dependency MyTest)

Here are the classes that I copied and customized. These files are all located under lib/generators/* These files were all copied from the railties gem folder and then modified e.g. railties/lib/rails/generators/rails/*

Ruby code:
#require 'rails/generators/rails/resource/resource_generator'
#require 'lib/generators/resource_dependency/resource_dependency_generator'

class ScaffoldDependencyGenerator < ResourceDependencyGenerator #Rails::Generators::NamedBase
  remove_hook_for :resource_controller
  remove_class_option :actions
  
  class_option :stylesheets, :type => :boolean, :desc => "Generate Stylesheets"
  class_option :stylesheet_engine, :desc => "Engine for Stylesheets"
  
  hook_for :scaffold_dependency_controller, :required => true
  
  #hook_for :assets do |assets|
  #  invoke assets, [controller_name]
  #end
  
  #hook_for :stylesheet_engine do |stylesheet_engine|
  #  invoke stylesheet_engine, [controller_name] if options[:stylesheets] && behavior == :invoke
  #end
  
  def add_phrases_to_en
    
    attributes.each do |_attr|
      unless ["account_id", "department_id"].include? _attr.name #build the string of fieldguides to create. exclude account_id and department_id
        _name = _attr.name
        if _attr.reference?
          _name = _name + "_id"
        end
        phrase_string = phrase_string + "\n    #{_name}: \"#{_attr.name.humanize}\""  
    
      end
    end
    
    phrase_string = phrase_string + "\r\n"
    
    #inject the field guide creation statement
    inject_into_file "config/locales/en.yml", :after => /#_auto_generator_hook\s/  do
      phrase_string
    end
               
  end #end add_phrases_to_en
  
  def add_relationship_to_account_model
    inject_into_file "app/models/account.rb", :after => /with_options :dependent => :destroy do \|acc\|/  do
      "\r\n\t\tacc.has_many :#{plural_table_name}"
    end
  end #end add_relationship_to_account_model
    

end

Ruby code:
require 'rails/generators/resource_helpers'
require 'rails/generators/rails/model/model_generator'
require 'active_support/core_ext/object/blank'

#module Rails
  #module Generators
    class ResourceDependencyGenerator < ModelDependencyGenerator #metagenerator
      include Rails::Generators::ResourceHelpers

      hook_for :resource_controller, :required => true do |controller|
        invoke controller, [ controller_name, options[:actions] ]
      end

      class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [],
                             :desc => "Actions for the resource controller"

      hook_for :resource_route, :required => true
    end
#  end
#end

Ruby code:
#module Rails
#  module Generators
    class ModelDependencyGenerator < Rails::Generators::NamedBase #metagenerator
      argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
      hook_for :orm, :required => true
      
      def thing
        Rails.logger.info("\n\n in the model dependency gen\n")
      end
    end
#  end
#end

And in the console, after running scaffold_dependency, all I get are unhelpful errors

Ruby code:
error active_record [not_found]
error resource_rote [not found]
etc...
ModelDependencyGenerator is ran, I can tell because the logger message is in my development.log. But why is it loving up on active_record?

KoRMaK fucked around with this message at 17:24 on Jan 19, 2014

Jaded Burnout
Jul 10, 2004


Jam2 posted:

I've designed some simple Ruby objects to model a problem and I like the way they're composed. I'd like to use them as the backend for a Rails app and persist the data to a database. How can I integrate this design into rails without having to make these classes inherit from ActiveRecordBase and tangle them together with the RailsWay of doing associations? Is that really the way to go? Ideally, I'd like to integrate this in a way such that the objects, at most, have some other object that they persist themselves to. I don't want to uglify this with Rails code. HALP!

ActiveModel is a mechanism provided with modern Rails to allow you to hook various bits of Rails code (e.g. validations, naming) into your models as required without relying on ActiveRecord itself. You could investigate that as a mechanism to allow you to use your Ruby objects as the basis for forms and other Rails helpers, while doing the persistence yourself.

That said, the interface and relationships you've already added to your code is almost identical to the way ActiveRecord operates, so if you're going to create something where the persistence is encapsulated within your models, you might as well use ActiveRecord.

Otherwise, you could write a repository object capable of persisting and restoring your models. ActiveModel can help with the serialization if you like.

Maybe more trouble than it's worth?

Jam2
Jan 15, 2008

With Energy For Mayhem

Arachnamus posted:

ActiveModel is a mechanism provided with modern Rails to allow you to hook various bits of Rails code (e.g. validations, naming) into your models as required without relying on ActiveRecord itself. You could investigate that as a mechanism to allow you to use your Ruby objects as the basis for forms and other Rails helpers, while doing the persistence yourself.

That said, the interface and relationships you've already added to your code is almost identical to the way ActiveRecord operates, so if you're going to create something where the persistence is encapsulated within your models, you might as well use ActiveRecord.

Otherwise, you could write a repository object capable of persisting and restoring your models. ActiveModel can help with the serialization if you like.

Maybe more trouble than it's worth?

Any examples of repository objects in the wild?

Jaded Burnout
Jul 10, 2004


Jam2 posted:

Any examples of repository objects in the wild?

Not many. There's a lot of talk around using a properly decoupled persistence layer in Rails but not a lot of walk. This guy seems to have had a decent stab at it: http://victorsavkin.com/post/41016739721/building-rich-domain-models-in-rails-separating and there's more on the theory in this article and the book / articles it references: http://devblog.avdi.org/2011/07/27/fowler-on-rails/

It was all the rage in 2009 and a couple of companies I know tried it out, but boy did it lead to a lot of extra work on the client dime, and was eventually scrapped. Rails has come a long way since then, so YMMV.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."
Well, I've been trying "rake db:seeds" and pointing to a file to do initial population. I as having issues with the data and ASCII vs unicode characters, and solved most of those by converting them to their HTML equivalents.

However, after resolving a few, I started getting a weird error:

code:
c:\Sites\AleSpace>rake db:seed
rake aborted!
end of file reached
<internal:prelude>:10:in `synchronize'
c:/Sites/AleSpace/db/seeds.rb:26:in `block (2 levels) in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:24:in `each_line'
c:/Sites/AleSpace/db/seeds.rb:24:in `block in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:23:in `<top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)
I changed my seeds.rb to point at a smaller 8 row file that worked earlier to import, thinking maybe the error was something that changed in my big file, but no dice.

My seeds.rb hasn't changed and looks like this:
code:
require 'open-uri'

Brewery.delete_all
open("http://www.alespace.com/brewtest.txt") do |breweries|
  breweries.read.each_line do |brewery|
    id, name, address, city, state, country, zip, brewerytype, web, facebook, twitter, email, phone = brewery.chomp.split("|")
    Brewery.create!(:id => id, :name => name, :address => address, :city => city, :state => state, :country => country, :zip => zip, :brewerytype => brewerytype, :web => web, :facebook => facebook, :twitter => twitter, :email => email, :phone => phone)
  end
end
Any ideas?

Jaded Burnout
Jul 10, 2004


raej posted:

Well, I've been trying "rake db:seeds" and pointing to a file to do initial population. I as having issues with the data and ASCII vs unicode characters, and solved most of those by converting them to their HTML equivalents.

However, after resolving a few, I started getting a weird error:

code:
c:\Sites\AleSpace>rake db:seed
rake aborted!
end of file reached
<internal:prelude>:10:in `synchronize'
c:/Sites/AleSpace/db/seeds.rb:26:in `block (2 levels) in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:24:in `each_line'
c:/Sites/AleSpace/db/seeds.rb:24:in `block in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:23:in `<top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)
I changed my seeds.rb to point at a smaller 8 row file that worked earlier to import, thinking maybe the error was something that changed in my big file, but no dice.

My seeds.rb hasn't changed and looks like this:
code:
require 'open-uri'

Brewery.delete_all
open("http://www.alespace.com/brewtest.txt") do |breweries|
  breweries.read.each_line do |brewery|
    id, name, address, city, state, country, zip, brewerytype, web, facebook, twitter, email, phone = brewery.chomp.split("|")
    Brewery.create!(:id => id, :name => name, :address => address, :city => city, :state => state, :country => country, :zip => zip, :brewerytype => brewerytype, :web => web, :facebook => facebook, :twitter => twitter, :email => email, :phone => phone)
  end
end
Any ideas?

The `synchronize` call is part of the multithreading code, and might be unrelated to the actual cause. Not even sure why that would be cropping up when you're just creating some objects. Maybe your UTF-8 problems aren't entirely gone?

Why are you loading the seed from a website, anyway?

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."

Arachnamus posted:

The `synchronize` call is part of the multithreading code, and might be unrelated to the actual cause. Not even sure why that would be cropping up when you're just creating some objects. Maybe your UTF-8 problems aren't entirely gone?

Why are you loading the seed from a website, anyway?

Thew tutorial had it set up from a website, so I figured why not. It also will help with testing since I'm running essentially dev locally on my machine, QA on one site, and production on the actual site. Same code will work on all 3 spots.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."

raej posted:

Thew tutorial had it set up from a website, so I figured why not. It also will help with testing since I'm running essentially dev locally on my machine, QA on one site, and production on the actual site. Same code will work on all 3 spots.

Deleted branch, and copied the code above to the same spots, no error. :iiam:

Jaded Burnout
Jul 10, 2004


raej posted:

Deleted branch, and copied the code above to the same spots, no error. :iiam:

welp

Newbsylberry
Dec 29, 2007

I Swim in drag shorts because I have a SMALL PENIS
I want to have invitations users can send to other users to join two different models, should I create an invitation model and then bridge tables for the respective models? It seems simpler to just create model1_invitation and model2_invitation, but smarter to create the bridge tables, what is the best practice?




Awesome, thanks for the help!

VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV

Newbsylberry fucked around with this message at 02:46 on Jan 24, 2014

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

Newbsylberry posted:

I want to have invitations users can send to other users to join two different models, should I create an invitation model and then bridge tables for the respective models? It seems simpler to just create model1_invitation and model2_invitation, but smarter to create the bridge tables, what is the best practice?

Use a polymorphic association: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Invitation belongs to invitable, and both of the invitable models have many invitations as invitable.

raej
Sep 25, 2003

"Being drunk is the worst feeling of all. Except for all those other feelings."
Is there a way to force Open-URI to use UTF-8? It defaults to US-ASCII so imports fail every time there is a special character:

Ruby code:
require 'open-uri'

Brewery.delete_all
open("http://www.alespace.com/breweriestest.csv") do |breweries|
  breweries.read.each_line do |brewery|
    id, name, address, city, state, country, zip, brewerytype, web, facebook, twitter, email, phone = brewery.chomp.split("|")
    Brewery.create!(:id => id, :name => name, :address => address, :city => city, :state => state, :country => country, :zip => zip, :brewerytype => brewerytype, :web => web, :facebook => facebook, :twitter => twitter, :email => email, :phone => phone)
  end
end
Error:
code:
c:\Sites\AleSpace>rake db:seed
rake aborted!
Encoding::UndefinedConversionError: "\xC3" from ASCII-8BIT to UTF-8: INSERT INTO
 "breweries" ("address", "brewerytype", "city", "country", "created_at", "desc",
 "email", "facebook", "id", "name", "phone", "state", "twitter", "updated_at", "
web", "zip") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
c:/Sites/AleSpace/db/seeds.rb:27:in `block (2 levels) in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:25:in `each_line'
c:/Sites/AleSpace/db/seeds.rb:25:in `block in <top (required)>'
c:/Sites/AleSpace/db/seeds.rb:24:in `<top (required)>'
Tasks: TOP => db:seed

Jaded Burnout
Jul 10, 2004


raej posted:

Is there a way to force Open-URI to use UTF-8? It defaults to US-ASCII so imports fail every time there is a special character:

If it is actually in UTF-8 you can tell Ruby what encoding a string is in using `String#force_encoding` e.g. `some_string.force_encoding("UTF-8")`.

If you need to actually change the encoding a string is in that's a little more complicated.

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
Kernel#open is mostly just an alias to IO::new, so the same options apply. Specify the encoding in the second parameter.
Ruby code:
open('http://foo.bar', 'r:UTF-8')

KoRMaK
Jul 31, 2012



How do I join a has_many relationship and order by one of the joined fields?

Here's an example:

@my_thing.persons.includes(:location).order("'persons.role' ASC, 'locations.name' ASC")

The above doesn't work. The sql changes the column names via a "as" call and so the order by clause is effectively useless because person.role and locations.name aren't available.


Uggghh it was a typo. I got too use to making things plural and person.role was typed as person.roles in the order clause.


I'd like to make this the default scope for that relationship on the my_thing model. I tried this but it doesn't work
Ruby code:
has_many :persons, include: :location, :order => "persons.role ASC, locations.name ASC"


Ughhh 2: The has_many declaration works fine. Its the stupid caching we have that was screwing up the render. It didn't think there was any change so it kept showing me the old cached render.

KoRMaK fucked around with this message at 17:24 on Jan 24, 2014

Jaded Burnout
Jul 10, 2004


Smol posted:

Kernel#open is mostly just an alias to IO::new, so the same options apply. Specify the encoding in the second parameter.
Ruby code:
open('http://foo.bar', 'r:UTF-8')

Didn't know about this flag. Cool.

Defghanistan
Feb 9, 2010

2base2furious
I am sorry to have to post with such a simple question but I've been internetting hard for about 12 hours and cant find a solution that works for me, which is crazy due to how simple of a problem this is.

I have a hash in the form of |k, v| string=>int and I want to get the average of all the int values. That's it.

My closest attempt is:
hash.inject(0) {|total, (k, v)| total + v.last}

But this is returning 'undefined method "last" for fixnum: (last integer value here)'

Can anyone provide me with a quick way of averaging a set of int values? I find it incredibly frustrating that this isn't just a builtin method.

KoRMaK
Jul 31, 2012



Defghanistan posted:

I am sorry to have to post with such a simple question but I've been internetting hard for about 12 hours and cant find a solution that works for me, which is crazy due to how simple of a problem this is.

I have a hash in the form of |k, v| string=>int and I want to get the average of all the int values. That's it.

My closest attempt is:
hash.inject(0) {|total, (k, v)| total + v.last}

But this is returning 'undefined method "last" for fixnum: (last integer value here)'

Can anyone provide me with a quick way of averaging a set of int values? I find it incredibly frustrating that this isn't just a builtin method.

v is already the value you want. No need for v.last, just v

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
If this is rails project or you're using active support anyway, use the following.

Ruby code:
hash.values.sum.to_f / hash.size
Otherwise use this.

Ruby code:
hash.reduce(0.0) { |sum, (k, v)| sum + v } / hash.size

Smol fucked around with this message at 17:33 on Jan 28, 2014

Defghanistan
Feb 9, 2010

2base2furious
Cool thanks for the replies guys, got it sorted!

Peristalsis
Apr 5, 2004
Move along.
I have a download action in a controller that's giving me some trouble.

The basic structure is this:

code:
if (user has selected some files on the page)
  construct a single zip file out of selected files
  send_file zipfile.path, :type => 'application/zip', :disposition => 'attachment', :filename => file_name
  zipfile.delete
else
  redirect_to calling page, with an alert that no files were selected
end
It works as is, and when the user specifies files, they get a file selection dialog, the zip file downloads from that, and the user drops back to the page with the list of files on it (apparently without refreshing).

My problem is that, in some cases after a successful download, I want to refresh that calling screen to put a list of certain files at the bottom. I tried putting a redirect_to in the first if-block, but got an error that I can only use one render or redirect per action. I figured Rails just wasn't smart enough to realize that only one of them could be called, so I tried to move the existing redirect after the if-else-end block and fiddle with the parameters, but that also gave me the same multiple render/redirect error.

So, I guess there must be an implicit render involved in the block with the send_to, but I don't know how to find, trace, or edit that. It doesn't seem to be using any actual view code, and rake routes shows me the route for getting into this download action, but I don't see anything that leads out of it to a view.

I'm sure I'm missing something simple, but I'm not sure where to go from here.

The Journey Fraternity
Nov 25, 2003



I found this on the ground!

Peristalsis posted:

I have a download action in a controller that's giving me some trouble.

The basic structure is this:

code:
if (user has selected some files on the page)
  construct a single zip file out of selected files
  send_file zipfile.path, :type => 'application/zip', :disposition => 'attachment', :filename => file_name
  zipfile.delete
else
  redirect_to calling page, with an alert that no files were selected
end
It works as is, and when the user specifies files, they get a file selection dialog, the zip file downloads from that, and the user drops back to the page with the list of files on it (apparently without refreshing).

My problem is that, in some cases after a successful download, I want to refresh that calling screen to put a list of certain files at the bottom. I tried putting a redirect_to in the first if-block, but got an error that I can only use one render or redirect per action. I figured Rails just wasn't smart enough to realize that only one of them could be called, so I tried to move the existing redirect after the if-else-end block and fiddle with the parameters, but that also gave me the same multiple render/redirect error.

So, I guess there must be an implicit render involved in the block with the send_to, but I don't know how to find, trace, or edit that. It doesn't seem to be using any actual view code, and rake routes shows me the route for getting into this download action, but I don't see anything that leads out of it to a view.

I'm sure I'm missing something simple, but I'm not sure where to go from here.

send_file is a 'renderer' here.

Peristalsis
Apr 5, 2004
Move along.

The Journey Fraternity posted:

send_file is a 'renderer' here.

Bummer.

Is there any way to edit or add to what it does? Or another way to force a refresh of the calling page?

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
It's not really possible to know if a file download has started or succeeded in JavaScript. Your best bet is to initiate the download via hidden iframe that links to the zip download url, setting a cookie in the zip response and polling for the cookie in your JS code.

KoRMaK
Jul 31, 2012



Peristalsis posted:

Bummer.

Is there any way to edit or add to what it does? Or another way to force a refresh of the calling page?
I swear I had to deal with something similiar but I kind of forget how. I think it involved using a javascript response. Don't send the file out via the first controller, but instead make the browser ajax request the file in your js response and then you can run a switch in the js response to see if it should do anything else.

Peristalsis
Apr 5, 2004
Move along.

Smol posted:

It's not really possible to know if a file download has started or succeeded in JavaScript. Your best bet is to initiate the download via hidden iframe that links to the zip download url, setting a cookie in the zip response and polling for the cookie in your JS code.

I don't think there's any JavaScript involved - this is all being done by http posts. I'm not worried at the moment about whether the download succeeds, I'm just trying to refresh the page that initiated the download after the send_file's render.

Edit:

KoRMaK posted:

I swear I had to deal with something similiar but I kind of forget how. I think it involved using a javascript response. Don't send the file out via the first controller, but instead make the browser ajax request the file in your js response and then you can run a switch in the js response to see if it should do anything else.

Ugh. This is all a bit beyond my expertise. Maybe I should just look for a way to send up a dialog or something with the file info for now.

Peristalsis fucked around with this message at 18:36 on Jan 30, 2014

Jaded Burnout
Jul 10, 2004


Peristalsis posted:

I don't think there's any JavaScript involved - this is all being done by http posts. I'm not worried at the moment about whether the download succeeds, I'm just trying to refresh the page that initiated the download after the send_file's render.

Edit:


Ugh. This is all a bit beyond my expertise. Maybe I should just look for a way to send up a dialog or something with the file info for now.

If you just want to display something after a download, you'd do better by putting it into the page that kicks off the download.

If you're wanting to only display something after a *successful* download, that's not really something you can do without an awful lot of faff.

Peristalsis
Apr 5, 2004
Move along.

Arachnamus posted:

If you just want to display something after a download, you'd do better by putting it into the page that kicks off the download.

If you're wanting to only display something after a *successful* download, that's not really something you can do without an awful lot of faff.

I want the former, but I don't have the information to display until the app starts processing the files to download. It's a list of files that are too large to download over the web app, and I get that list by looking at the file type of all the files selected by the user. Until the user selects the files and submits the list, I don't know which files can be downloaded.

However, I could just mark all the non-downloadable files on the page with an asterisk and footnote to begin with, to let the user know that those files will just have their network locations/paths listed in a text file instead. Maybe my boss will go for that.

If not, his last suggestion was to render a separate confirmation page that listed which files will be downloaded and which won't, and make the user submit from that form to start the actual download. I think that'll work, too, but it's a lot more hassle, and might not be much easier than just learning all this JavaScript stuff.

Thanks for the ideas!

Jaded Burnout
Jul 10, 2004


Peristalsis posted:

I want the former, but I don't have the information to display until the app starts processing the files to download. It's a list of files that are too large to download over the web app, and I get that list by looking at the file type of all the files selected by the user. Until the user selects the files and submits the list, I don't know which files can be downloaded.

However, I could just mark all the non-downloadable files on the page with an asterisk and footnote to begin with, to let the user know that those files will just have their network locations/paths listed in a text file instead. Maybe my boss will go for that.

If not, his last suggestion was to render a separate confirmation page that listed which files will be downloaded and which won't, and make the user submit from that form to start the actual download. I think that'll work, too, but it's a lot more hassle, and might not be much easier than just learning all this JavaScript stuff.

Thanks for the ideas!

You could also tag the files which are known to be too large using a data attribute or a CSS class, then use javascript to build the in-page list of files that won't be downloaded as the user is selecting them.

kayakyakr
Feb 16, 2004

Kayak is true

Peristalsis posted:

I want the former, but I don't have the information to display until the app starts processing the files to download. It's a list of files that are too large to download over the web app, and I get that list by looking at the file type of all the files selected by the user. Until the user selects the files and submits the list, I don't know which files can be downloaded.

However, I could just mark all the non-downloadable files on the page with an asterisk and footnote to begin with, to let the user know that those files will just have their network locations/paths listed in a text file instead. Maybe my boss will go for that.

If not, his last suggestion was to render a separate confirmation page that listed which files will be downloaded and which won't, and make the user submit from that form to start the actual download. I think that'll work, too, but it's a lot more hassle, and might not be much easier than just learning all this JavaScript stuff.

Thanks for the ideas!

You can also use a redirector on the confirmation page if you don't have an absolute need to submit a post. To do this, when they hit download, you would send them to a download page and then use JS to open the download link 5 seconds later. Send the files as 'attachment' and they'll never leave the confirmation page.

If you need the post, consider instead creating a temporary download object that holds which files you need to send, so you will have something to redirect to.

Peristalsis
Apr 5, 2004
Move along.

Arachnamus posted:

You could also tag the files which are known to be too large using a data attribute or a CSS class, then use javascript to build the in-page list of files that won't be downloaded as the user is selecting them.


kayakyakr posted:

You can also use a redirector on the confirmation page if you don't have an absolute need to submit a post. To do this, when they hit download, you would send them to a download page and then use JS to open the download link 5 seconds later. Send the files as 'attachment' and they'll never leave the confirmation page.

If you need the post, consider instead creating a temporary download object that holds which files you need to send, so you will have something to redirect to.

Thanks for the additional ideas. I don't care about posting or not posting, I'm just trying to get a fix out for this as quickly as possible (i.e. changing as little of the code and structure as I can at this point). For the next version, we'll want something better than my footnote though (my boss went for that idea, so I'm on to the next artificially induced crisis), so I'll try to look into integrating JavaScript and whatnot. I've been able to work primarily on the back end of this app, and now that I'm getting UI stuff thrown at me, I need to figure out what the hell I'm doing with HTML, css, and JavaScript.

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

Anyone have experience with Carrierwave uploads into an accepts_nested_attributes_for object? The child object is created just fine with the other properties. But the upload part just won't take.

KoRMaK
Jul 31, 2012



These are code blocks right? (the failure/succes.html{} bit)

Ruby code:
class ProjectsController < InheritedResources::Base
  def update
    super do |success, failure|
      failure.html { redirect_to project_url(@project) }
      success.html { Rails.logger.info("Success") }
    end
  end
end
https://github.com/josevalim/inherited_resources

I'm using inherited_resources. I've come accross a situation where both my .js and .html responses should be the same. How do I combine them?

Ruby code:
class ProjectsController < InheritedResources::Base
  def update
    super do |success, failure|
      failure.html { redirect_to project_url(@project) }
      success.html { Rails.logger.info("Success") }
      success.js { Rails.logger.info("Success") }
    end
  end
end
Should be

Ruby code:
class ProjectsController < InheritedResources::Base
  def update
    super do |success, failure|
      failure.html { redirect_to project_url(@project) }
      success.html, success.js { Rails.logger.info("Success") }
    end
  end
end
I thought I was close when i did this, but it turns out I was wrong and that my code is just getting run twice and causes double render errors.
Ruby code:
class ProjectsController < InheritedResources::Base
  def update
    super do |success, failure|
      failure.html { redirect_to project_url(@project) }
      [success.html, success.js].each { Rails.logger.info("Success") }
    end
  end
end

kayakyakr
Feb 16, 2004

Kayak is true
try:

Ruby code:
success.all { Rails.logger.info("Success") }

KoRMaK
Jul 31, 2012



kayakyakr posted:

try:

Ruby code:
success.all { Rails.logger.info("Success") }
Wow yea that worked. Thank you. How would I have figured this out on my own? What is the success object? An inspect says its a ActionController::MimeResponds::Collector but that doesn't really tell me how I could have figured out that .all would have worked.

edit: oh duh, the help page does inform me of .all http://apidock.com/rails/ActionController/MimeResponds/Collector

Let's say that I want .html and .js to share a response, but .json to return a different thing. What would the statements look like then?

e: Found it down the page here http://edgeapi.rubyonrails.org/classes/ActionController/MimeResponds.html

Ruby code:
success.any(:js, :html) { Rails.logger.info("\n\n Success \n\n") }
OR

Ruby code:
success.all(:js, :html) { Rails.logger.info("\n\n Success \n\n") }

KoRMaK fucked around with this message at 17:54 on Feb 3, 2014

Adbot
ADBOT LOVES YOU

kayakyakr
Feb 16, 2004

Kayak is true

KoRMaK posted:

Let's say that I want .html and .js to share a response, but .json to return a different thing. What would the statements look like then?

e: Found it down the page here http://edgeapi.rubyonrails.org/classes/ActionController/MimeResponds.html

Ruby code:
success.any(:js, :html) { Rails.logger.info("\n\n Success \n\n") }
OR

Ruby code:
success.all(:js, :html) { Rails.logger.info("\n\n Success \n\n") }

I also believe that it falls through (or fails to do so). So if you have success.json on the first line and then success.all on the second line, it'll respond with the json line and not the all line.

Don't quote me on that, it might cause a double render as well.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply