1

(0 replies, posted in Ruby on Rails)

I have a field that I need to validate the presence of an entry, but it's from a different model.

Here's the view code...

        <%= text_field_with_auto_complete :agency, :code, {:value => @line_item, :size => 31}, :skip_style => true %>

Here's the controller store/checkout

  def checkout
    @title = "Please enter your information to continue this purchase."
    # @cc_processor = Order.get_cc_processor
    # @agency_codes = Agency.find(:all)
    if request.get?
      unless @order.has_been_placed? then
        # Save standard form info
        logger.info("\n\nNEW ORDER INIT\n\n")
        initialize_new_order
      else
        logger.info("\n\nEXISTING ORDER INIT\n\n")
        initialize_existing_order
      end
      render :layout => 'checkout' and return
    elsif request.post?
      @agency_title = params[:agency_title]
      @agency_code = params[:agency][:code]
      @line_itemz = @order.order_line_items.find(:all)
      @line_itemz.each do |item|
        item.agency_code = @agency_code.strip
        item.shipping_total = 0.00
        item.save!
      end
      @line_itemzz = @order.order_line_items.find(:first)
      @line_itemzz.shipping_total = 10.95
      @line_itemzz.save!

      @line_items = @order.order_line_items.find(:all, :conditions => "agency_name = 1")
      @line_items.each do |item|
        item.agency_title = @agency_title
        item.save!
      end
      do_checkout()
    end
  end

Basically, I want to make sure that the person has selected a value for the agency code.  This agency code gets assigned to the item, and I'm struggling to get it to validate when it's being used in the store controller.

Also, this controller code is hideous, so any  advice is appreciated smile

Zack

2

(0 replies, posted in Ruby on Rails)

I'm trying to use Ultrasphinx in my latest application (I've always used Ferret, but I thought I tried out a new full-text search engine).  I have sphinx setup, and ultrasphinx in my app, and the default.base configured as such...

#
# Sphinx/Ultrasphinx user-configurable options.
#
# Copy this file to RAILS_ROOT/config/ultrasphinx. You can use individual 
# namespaces if you want (e.g. development.base, production.base, 
# test.base). Note that ERb is also allowed.
#
# This file should not be handed directly to Sphinx. Use the rake task 
#
#   rake ultrasphinx::configure
#
# to generate a parallel default.conf file. This is the file that Sphinx itself will
# use. The Ultrasphinx rake tasks automatically pass the correct file to 
# to Sphinx.
# 
# It is safe to edit .base files by hand. It is not safe to edit the generated 
# .conf files. Do not symlink the .conf file to the .base file; it's wrong.
#

<% path = "/opt/local/var/db/sphinx/" %>

# Indexing options
indexer
{  
  mem_limit = 256M 

  # Ultrasphinx-specific key
  delta = <%= 1.day + 30.minutes %> 
}

# Daemon options
searchd 
{ 
address = 0.0.0.0 
port = 3312 
log = log/searchd.log 
query_log = log/query.log 
read_timeout = 5 
max_children = 300 
pid_file = log/searchd.pid 
max_matches = 100000 
}

# Client options
client
{
  # Name of the Aspell dictionary (two letters max)
  dictionary_name = ap
  
  # How your application connects to the search daemon (not necessarily the same as above)
  server_host = localhost
  server_port = 3313
}

# Individual SQL source options
source
{  
  sql_ranged_throttle = 0  
  sql_range_step = 5000   
  sql_query_post =
  strip_html = 1
}

# Index building options
index
{  
  path = sphinx
  docinfo = extern # Just leave this alone
  morphology = stem_en
  stopwords = # <%= path %>/ap-stopwords.txt
  min_word_len = 1

  # HTML-specific options
  html_strip = 0
  html_index_attrs =
  
  # Enable these if you need wildcard searching. They will slow down indexing significantly.
  #   min_infix_len = 1    
  #   enable_star = 1 

  # # URL search options
  # # add " @, /, :," before " a-z," in the charset_table and uncomment prefix_fields
  # to seach URL and email addresses
  # prefix_fields = url, domain
    
  charset_type = utf-8 # or sbcs (Single Byte Character Set)
  charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z,
}

Everything starts up fine when  I run rake ultrasphinx:bootstrap, but if I try to script/console and query the index, I get connection errors.

>> @search = Ultrasphinx::Search.new(:query => 'biomedical')
=> #<Ultrasphinx::Search:0x1875234 @facets={}, @response={}, @results=[], @options={"indexes"=>"main", "class_names"=>[], "sort_by"=>nil, "parsed_query"=>"biomedical", "sort_mode"=>"relevance", "filters"=>{}, "weights"=>{}, "per_page"=>20, "query"=>"biomedical", "page"=>1, "facets"=>[], "location"=>{"units"=>"radians", "long_attribute_name"=>"lng", "lat_attribute_name"=>"lat"}}, @subtotals={}>
>> @search.run
Errno::ECONNREFUSED: Connection refused - connect(2)
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:387:in `initialize'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:387:in `new'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:387:in `connect'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:415:in `request'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:170:in `run'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/../vendor/riddle/lib/riddle/client.rb:277:in `query'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/ultrasphinx/search.rb:341:in `run'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb:352:in `perform_action_with_retries'
	from /Users/zack/Dropbox/website/vendor/plugins/ultrasphinx/lib/ultrasphinx/search.rb:340:in `run'
	from (irb):4

I've queried Google all day and have had no luck.  I downloaded / compiled all of this today.  This is on Rails 2.1.1 and Sphinx 0.9.8-rc2 on Leopard 10.5.6.  Has anybody seen / solved this before?

**EDIT** I solved it.  Here's a situation where a little proofreading on my part would have really helped.  In my config file, I have searchd (the ultrasphinx daemon) running on port 3312, and the clients trying to connect to it with port 3313.  A simple edit of my config file, and re-running the rake task has everything working now.


Thanks,
Zack

3

(10 replies, posted in Ruby on Rails)

Thank you very much, that cleans the controller up a ton!  This has been a great learning experience for me.

Zack

4

(10 replies, posted in Ruby on Rails)

Okay, this seems to work better, but it seems very strange to call this from a controller...

  def reporter
    @tax_id = '123456789'
    @orders = Order.find(:all, :conditions => ["created_on > ?", Time.now - 30.days])
    File.delete("/Users/zack/Desktop/general_report_#{Time.now.strftime("%m%d%Y")}.txt") if File::exists?( "/Users/zack/Desktop/general_report_#{Time.now.strftime("%m%d%Y")}.txt" )
    sleep 5
    f = File.open("/Users/zack/Desktop/general_report_#{Time.now.strftime("%m%d%Y")}.txt", 'w')
    @orders.each do |order|
      order.order_line_items.each do |item|
        @base_price = Item.find(item.item_id).price.to_f
        @subtotal = (@base_price*item.quantity)
        @code = Item.find(item.item_id).code.split(/_/).first.downcase.ljust(10," ")
        @tax = (item.unit_price*0.06)
        @difference = (item.unit_price-@base_price)
        @total = (@subtotal + @tax + @difference + item.shipping_total.to_f)
        f.write(@tax_id)
        f.write(item.agency_code.gsub("-","").rjust(8,"0"))
        f.write(@code)
        f.write(item.quantity.to_s.rjust(7,"0"))
        f.write((number_with_precision(@base_price, precision=2)).to_s.gsub(".","").rjust(8,"0"))
        f.write("+")
        f.write((number_with_precision(@subtotal, precision=2)).to_s.gsub(".","").rjust(9,"0"))
        f.write("+")
        f.write(number_with_precision(@tax, precision=2).to_s.gsub(".","").rjust(8,"0"))
        f.write("+")
        f.write(number_with_precision(@difference, precision=2).to_s.gsub(".","").rjust(8,"0"))
        f.write("+")
        f.write(item.shipping_total.to_s.gsub(".","").rjust(8,"0"))
        f.write("+")
        f.write(number_with_precision(@total, precision=2).to_s.gsub(".","").gsub(".","").rjust(10,"0"))
        f.write("+")
        f.write(order.created_on.strftime("%m%d%Y"))
        f.write(order.order_number)
        f.write("\n")
      end    
    end
        f.close
        render :nothing => true
  end

5

(10 replies, posted in Ruby on Rails)

Okay,this works, kind of,  but I seem to have to hit the action twice to get the report populated. Here's the output format I want for one line.

12345678901010300ch100     000000100002430+000002430+00000164+00000300+00001095+0000003989+100620087762476

I'm getting it, but on multiple lines, it's like the \n stops working or I have to perform the action 2 or 3 times to get it to populate the report (then I get duplicates...

12345678901000400ch100w    000000112345678901000400ch100w    000000112345678901000400ch100w    000000100002430+000002430+00000164+00000300+00001095+0000003989+100620085703677
123456789010004008350      000000100002725+000002725+00000164+00000000+00000000+0000002889+100620085703677
12345678901014000ch100w    000000200002430+000004860+00000164+00000300+00001095+0000006419+100620085284059
12345678901014000107       000000100002435+000002435+00000146+00000000+00000000+0000002581+100620085284059
12345678901010300ch100     000000100002430+000002430+00000164+00000300+00001095+0000003989+100620087762476

Duplicated 3 times...

12345678901010300ch100     000000200002430+000004860+00000164+00000300+00001095+0000006419+100620082660427
123456789010103008350      000000100002725+000002725+00000164+00000000+00000000+0000002889+100620082660427
1234567890101030013v0527   000000100002870+000002870+00000190+00000300+00000000+0000003360+100620082660427
12345678901010300ch100     000000200002430+000004860+00000164+00000300+00001095+0000006419+100620082660427
123456789010103008350      000000100002725+000002725+00000164+00000000+00000000+0000002889+100620082660427
1234567890101030013v0527   000000100002870+000002870+00000190+00000300+00000000+0000003360+100620082660427
12345678901010300ch100     000000200002430+000004860+00000164+00000300+00001095+0000006419+100620082660427
123456789010103008350      000000100002725+000002725+00000164+00000000+00000000+0000002889+100620082660427
1234567890101030013v0527   000000100002870+000002870+00000190+00000300+00000000+0000003360+100620082660427

You'll notice the second line didn't honor the newline entry.

Thanks,
Zack

6

(10 replies, posted in Ruby on Rails)

Well, I've taken ryenski's method and made my report, but it's still not exactly pretty.  I have this all in the Orders Controller.

  def reporter
    @tax_id = '123456789'
    @orders = Order.find(:all, :conditions => ["created_on > ?", Time.now - 30.days])
    f = File.open("/Users/zack/Desktop/general_report_#{Time.now}.txt", 'a+')
    @orders.each do |order|
      order.order_line_items.each do |item|
        @base_price = Item.find(item.item_id).price.to_f
        @subtotal = (@base_price*item.quantity)
        @code = Item.find(item.item_id).code.split(/_/).first.downcase.ljust(10," ")
        @tax = (item.unit_price*0.06)
        @difference = (item.unit_price-@base_price)
        @total = (@subtotal + @tax + @difference + item.shipping_total.to_f)
        f.write(@tax_id)
        f.write(item.agency_code.gsub("-","").rjust(8,"0"))
        f.write(@code)
        f.write(item.quantity.to_s.rjust(7,"0"))
        f.write((number_with_precision(@base_price, precision=2)).to_s.gsub(".","").rjust(8,"0"))
        f.write((number_with_precision(@subtotal, precision=2)).to_s.gsub(".","").rjust(9,"0"))
        f.write(number_with_precision(@tax, precision=2).to_s.gsub(".","").rjust(8,"0"))
        f.write(number_with_precision(@difference, precision=2).to_s.gsub(".","").rjust(8,"0"))
        f.write(item.shipping_total.to_s.gsub(".","").rjust(8,"0"))
        f.write(number_with_precision(@total, precision=2).to_s.gsub(".","").gsub(".","").rjust(10,"0"))
        f.write(order.created_on.strftime("%m%d%Y"))
        f.write(order.order_number)
        f.write("\n")
      end
    end    
    render :nothing => true
  end

It's not working consistently, and it doesn't seem to honor the newline message. Any input is appreciated.

Thanks,
Zack

7

(10 replies, posted in Ruby on Rails)

ryenski, that's exactly the clean code I knew I should have THANK YOU smile

I'm going to order.order_line_items that I will be iterating through, and will need to output this data into a text file with Windows new line breaks.  Have any advice on that?

8

(10 replies, posted in Ruby on Rails)

I code do this with a case statement, but this seems very ugly...

>> @price = price.to_s.length
>> case
?> when @price = 4
>> '000' + price.to_s
>> when @price = 5
>> '00' + price.to_s
>> when @price = 6
>> '0' + price.to_s
>> else price
>> end
=> "00043.3"

9

(10 replies, posted in Ruby on Rails)

I need to put together a text file for a company I'm doing some work for that has to be in a specific format (text delimited).  Each billing code has to be a certain length, say 7 digits.  If the number you're putting in that area isn't 7 digits long, you need to put zeroes in front of it. Like this...

@cost = 4523
I'd like it to output...
0004523

If it's 5 digits long it would still need to work

@cost = 25363
output...
0025363

I need a Ruby method that will evaluate the proper length for that field, and if it's too short, puts the appropriate number of zeroes in front.

Thanks,
Zack

Thanks ryenski!

I haven't tried rolling jquery into any of my Rails apps yet.  I am running Rails 2.1.1, so that won't be the cure for me in this occasion, but thanks for the suggestion smile

I'm definitely going to check out JRails, but I'd hate to add a new plugin in for just one goofy action if I don't have to.  I just wonder if there's a better way to structure the code, so Prototype can serialize it?

**UPDATE**
I just installed the JRails plugin, and unfortunately that didn't fix it either...

Thanks again,
Zack

I'm using the newest version of Substruct and trying to add sizes to my items.  For some reason, when I try to pick more than one size for an item, it only saves the first one.  In looking at the COMMIT log, a hash is being generated for each selection I make, and it's only saving the first item.  Here's what my code looks like.  Also, I had to add the collection in the view (which is hideous). So I could use some help on moving this back to the controller.

edit action

 def edit
   @title = "Editing A Product"
   @product = Product.find(params[:id])
   @image = Image.new
end

save action

def save
    # If we have ID param this isn't a new product
    if params[:id]
      @new_product = false
      @title = "Editing Product"
      @product = Product.find(params[:id])
      @size = Size.find(:all)
    	@product.sizes = Size.find(params[:size_ids]) if params[:size_ids]
    else
      @new_product = true
      @title = "New Product"
      @product = Product.new()
    end
    @product.attributes = params[:product]
    @size = Size.find(:all)
  	@product.sizes = Size.find(params[:size_ids]) if params[:size_ids]
		if @product.save
			# Save product tags
			# Our method doesn't save tags properly if the product doesn't already exist.
			# Make sure it gets called after the product has an ID
			@product.tag_ids = params[:product][:tag_ids] if params[:product][:tag_ids]
      # Build product images from upload
      image_errors = []
      unless params[:image].blank?
  			params[:image].each do |i|
          if i[:image_data] && !i[:image_data].blank?
            new_image = Image.new
            logger.info i[:image_data].inspect
            new_image.uploaded_data = i[:image_data]
            new_image.description = i[:image_description]
            if new_image.save
              @product.images << new_image
            else
              image_errors.push(new_image.filename)
            end
          end
        end
      end

      # Build downloads from form
      download_errors = []
      unless params[:download].blank?
  			params[:download].each do |i|
          if i[:download_data] && !i[:download_data].blank?
            new_download = Download.new
            logger.info i[:download_data].inspect
          
            new_download.uploaded_data = i[:download_data]
            if new_download.save
              new_download.product = @product
            else
              download_errors.push(new_download.filename)
            end
          end
        end
      end

      # Build variations from form
      if !params[:variation].blank?
        params[:variation].each do |v|
          variation = @product.variations.find_or_create_by_id(v[:id])
          variation.attributes = v
          variation.sizes = Size.find(params[:size_ids]) if params[:size_ids]
          variation.save
          @product.variations << variation
        end
      end
      
      flash[:notice] = "Product '#{@product.name}' saved."
      if image_errors.length > 0
        flash[:notice] += "<b>Warning:</b> Failed to upload image(s) #{image_errors.join(',')}. This may happen if the size is greater than the maximum allowed of #{Image::MAX_SIZE / 1024 / 1024} MB!"
      end
      if download_errors.length > 0
        flash[:notice] += "<b>Warning:</b> Failed to upload file(s) #{download_errors.join(',')}."
      end
      redirect_to :action => 'edit', :id => @product.id
    else
			@image = Image.new
			if @new_product
        render :action => 'new' and return
      else
        render :action => 'edit' and return
      end
    end    
  end

form.rhtml

<div id="variation_container">
  <%= render :partial => 'variation', :collection => @product.variations %>
</div>

variation partial

<div class="variation">
	<input type="hidden" name="variation[][id]" value="<%= variation.id %>" />
	<div class="float">
		<%= make_label('Name', true) %>
		<%= text_field_tag('variation[][name]', variation.short_name, :size => 30, :class => 'textInput') %>
		<br/>
		<span class="info">ie: Red XXL</span>
	</div>
	<div class="float">
		<%= make_label('Product Code', true) %>
		<%= text_field_tag('variation[][item]', variation.item, :size => 10, :class => 'textInput') %>
	</div>
	<div class="float">
		<%= make_label('Price') %>
		<%= text_field_tag('variation[][price]', variation.price, :size => 6, :class => 'textInput numeric') %>
	</div>
	<div class="float">
		<%= make_label('Quantity') %>
		<%= text_field_tag('variation[][quantity]', variation.quantity, :size => 6, :class => 'textInput numeric') %>
	</div>
	<div class="float">
		<%= make_label('Size') %>
		<% @size = Size.find(:all) %>
		<% @selected = variation.sizes.collect { |cat| cat.id.to_i } %>
		<select id="sizes" name="variation[][size_ids][]" multiple="multiple" size="5", :class => 'textInput'>
		<%= options_from_collection_for_select(@size, "id", "name", @selected) %>
		</select>
	</div>
	<!-- remove link -->
	<div style="float:right;margin-top:20px;">
		<%= 
			link_to_remote image_tag("icons/png-24/16-em-cross.png", :plugin => 'substruct', :alt => 'Delete'),
	    	{
					:url => { :action => "remove_variation_ajax", :id => variation.id },
					:loading => "$('remove_variation_link_#{variation.id}').hide(); $('variation_indicator_#{variation.id}').show();",
	    		:complete => "$('remove_variation_link_#{variation.id}').up('.variation').remove();"
				},
				:id => "remove_variation_link_#{variation.id}"
		%>
		<%= image_tag("/indicator.gif", :plugin => 'substruct', :style => 'display:none;', :id => "variation_indicator_#{variation.id}") %>
	</div>
	<div class="clear"></div>
</div>

The issue is with the code from this line...

<%= options_from_collection_for_select(@size, "id", "name", @selected) %>

The output of a save looks like this...

Processing ProductsController#save (for 127.0.0.1 at 2008-09-16 15:49:53) [POST]
  Session ID: 554d8bcf1aab0fe069f8f445e8b92716
  Parameters: {"variation"=>[{"name"=>"asdfasd", "code"=>"dfd", "price"=>"10.2", "quantity"=>"12", "id"=>"1221593973", "size_ids"=>["2"]}, {"name"=>"sdff", "code"=>"dafdsf", "price"=>"10.2", "quantity"=>"0", "id"=>"1221593980", "size_ids"=>["3"]}, {"size_ids"=>["5"]}, {"size_ids"=>["9"]}], "commit"=>"Save This Product", "product"=>{"name"=>"Ladies Fleece Jacket", "size_width"=>"0", "weight"=>"0", "code"=>"7420", "date_available(1i)"=>"2008", "size_height"=>"0", "description"=>"Warm up to comfort and style in the Arctic women’s 10.2 oz. heavyweight 100% spun polyester Anti-Pilling PANDA FLEECE jacket. Featuring nylon panels on the front and back yoke, back forearms and along the bottom. Accented with chest and side zippered pockets, elastic-bound cuffs and the EMB-AXS system for clean embroidery. Adjustable drawstring bottom with cord locks provides a custom fit. Slight drop tail.", "date_available(2i)"=>"9", "date_available(3i)"=>"15", "tag_ids"=>["", "3"], "is_discontinued"=>"0", "related_product_ids"=>["", "", "", "", ""], "size_depth"=>"0"}, "action"=>"save", "id"=>"1221483855", "controller"=>"admin/products", "image"=>[{"image_description"=>"", "image_data_temp"=>"", "image_data"=>""}, {"image_description"=>"", "image_data_temp"=>"", "image_data"=>""}]}

If you see this variation has 3 size_id hashes, instead of 1 size_ids array.

{"name"=>"sdff", "code"=>"dafdsf", "price"=>"10.2", "quantity"=>"0", "id"=>"1221593980", "size_ids"=>["3"]}, {"size_ids"=>["5"]}, {"size_ids"=>["9"]}]

Any help you can provide is greatly appreciated!

Thanks,
Zack

12

(16 replies, posted in Ruby on Rails)

Adam,

I kind of gave up on using Net/FTP and went the MERB route.  It's worked very well for us over the last few months.  I just integrated it into our existing public Rails app.  This tutorial walks you through it.

http://www.scribelabs.com/2007/10/18/fi … rt-1-of-3/

13

(12 replies, posted in Ruby on Rails)

Leovenous,

You shouldn't need both if you're only iterating through the @issues.  That will pull in all the issues for you. Also, you might want to add a condition, so that as you gain many articles, you can move "older" ones into an archive.  You could do this with a date condition, or a field_that you set with a checkbox like this.  Also you might want to order them by date so that the most recent shows up at the top.

@issues = Issue.find(:all, :conditions => ["archive != 1 and published = 1"], :include => [:articles], :order => "created_at DESC" )

This would find all the published Issues that aren't archived and put the most recent at the top, and pull in the associated articles.

Can you paste the code from your partial, I don't have time to checkout your code and setup the app at work.  But I'll take a look if you paste it.

Zack

14

(12 replies, posted in Ruby on Rails)

Leovenous,

I haven't been a part of this topic, but I'll try to help you to understand some of the fine code that's been suggested to you.  In regards to ryenski's code, the :include => [:articles] is called eager loading. 

If you were to iterate through all the issues and then all of the articles associated with it,  you would have multiple queries going to the server.  In loading the page, each issue would also result in another query to the server to return it's articles.

By using ryenski's example, and taking advantage of Rails’s eager loading feature, you can greatly reduce the number of queries required. Using as suggested, results in one query, instead of many (depending on how many issues, and articles you have).

As an added bonus, you get code that's easier to understand smile 

I hope that helps.

15

(5 replies, posted in Ruby on Rails)

Wow! Thanks to both of you, my method seemed way to complicated for what I was trying to do.  strftime kept returning the number for the month rather than the name of the month. So, on a date in my database like this 2007-10-30.

@article.date.year #=> "2007"
@article.date.day #=> "30"
@article.date.month #=> "10"

I'd like to show Oct, instead of 10 for the month of October, and the month method or strftime("%b") doesn't seem to return that for me in this case.

Thanks for the heads up on putting the Time formatting in the initializers, I've always put that kind of stuff in a helper.

Zack

16

(5 replies, posted in Ruby on Rails)

I have a confusing method that I'm trying to cleanup.  The the database I have the date stored in a format like this 2007-03-19.  I want to display the articles Month, Day, and Year stacked on top of each other in the view.  This is what I have at this point, and my article methods seem a bit inefficient.

Here's my controller

  
def index
    @months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    @articles = Article.find(:all, :conditions => "is_current = 1 ", :order => "date desc")
end

Here's my model

class Article < ActiveRecord::Base
  
  def month_number_to_words
    month_number = (self.date.to_s.split(/-/).values_at(1).to_s.to_i) - 1
    if month_number == 10 
      then month_number
      else month_number.to_s.gsub(/0*/,"").to_i 
    end
  end
  
  def day_of_the_month
    self.date.to_s.split(/-/).slice(2)
  end
  
  def year_written
    self.date.to_s.split(/-/).values_at(0)
  end      
end

And finally my view...

<div id="content_body">
<h3>Current Articles</h3>

<% @articles.each do |article| %>
<div class="article_summary">
	<div class="date">
		<span class="month"><%= @months.slice(article.month_number_to_words) %></span>
		<span class="day"><%= article.day_of_the_month %></span>
		<span class="year"><%= article.year_written %></span>
	</div>
	<p>
	<span class="title"><%= link_to article.headline, :action => "show", :id => article.id -%></span>
		<%= truncate(article.body, 250) %>
		<%= link_to "Read More", :action => "show", :id => article.id %>
	</p>
</div>
<% end %>
</div>

It all works, but is efficient and has way to many conversions from strings, integers, and arrays. Plus, the methods are not very understandable.  Any input is greatly appreciated.

Thanks,
Zack

17

(16 replies, posted in Ruby on Rails)

Ace of Dubs,

MERB is actually really easy.  Unfortunately, I don' have any examples of integrating it into Rails because, my previous app was so simple, I just re-wrote it completely as a a MERB app.  MERB now supports RESTful routes, including nesting, so it made much of my code, copy and paste.

All you'd need to do is have Rails do it's upload post request to your MERB server, it runs on port 4000 by default, and it should be that easy.

***WARNING: Much of this code is taken from the attachment_fu plugin. ***

Here is a little example of my upload action...

   @upload = UserFile.new
   @upload.attributes = {
     :filename      =>  params[:data][:filename],
     :filesize      =>  params[:data][:size],
     :content_type  =>  params[:data][:content_type],
     :user_id       =>  current_user
   }
   @upload.save!
   destination = MERB_ROOT+"/public/uploads/#{@upload.filename}"
   FileUtils.mv params[:data][:tempfile].path, destination
   render_no_layout

And my Model code, to clean up the IE file path bugs...

class UserFile < ActiveRecord::Base
  before_save :sanitize

  def sanitize
     self.filename.gsub!(/^.*(\\|\/)/, '')
     self.filename.gsub!(/[^\w\.\-]/,'_') 
  end
end

I'm still refactoring my code, so don't beat me up on it too bad.  I'm very impressed with MERB, I've tested it with files as large as 1.5GB, and it handled it with no problems at all, while still managing other uploads (Something that's impossible in Rails).

As Robert suggests, backgrounddb is great, but I just found MERB to be easier to implement in this case, and it's been something I've been wanting to mess around with for a while.

Zack

18

(16 replies, posted in Ruby on Rails)

ryenski,

I really don't want to rip a hole through the space-time continium, so I'll avoid send_file and stick with your advice and do a straight HTTP download from the public folder.

I didn't end up using FTP, I'm using MERB (Mongrel + ERB) temporarily.  I'm still working on the FTP backend, NET::FTP is very simple, but passing the stream through Rails is the tough part. I don't know if I'll ever get it get it working, but it has been fun working on it.

For the record, MERB seems very capable of handling huge file uploads / downloads.  I just uploaded a 3 gb file to it, with no problem.  The next phase will be to integrate this into my existing Rails App.

Thanks again,
Zack

19

(16 replies, posted in Ruby on Rails)

ryenski,  Thanks for the upload links.  Some of those look very good, but I'm dealing with people that might get confused by an Ajax / Flash form (Scary, considering that they're Architects). So, I've got this working using MERB.  I've sent files between 500MB and 1GB and haven't had a hiccup yet.  But I can't for the life of me figure out how to get the uploaded files back from the server.  It has a send_file method, and I tried to use it in my controller, but I keep getting can't convert nil into String - (TypeError messages).

Here's what I have in the controller

def file
    send_file params[:filename]
end

I've tried passing it the id, the filename, the whole path to the file, but it's not working.  This the MERB documentation on the method...

     # File lib/merb/mixins/controller_mixin.rb, line 168
     def send_file(file, opts={})
       opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
       disposition = opts[:disposition].dup || 'attachment'
       disposition << %(; filename="#{opts[:filename] ? opts[:filename] : File.basename(file)}")
       headers.update(
         'Content-Type'              => opts[:type].strip,  # fixes a problem with extra '\r' with some browsers
         'Content-Disposition'       => disposition,
         'Content-Transfer-Encoding' => 'binary',
         'X-SENDFILE'                => file
       )
       return
    end

It looks like it just requires the filename, but I can't seem to get it working.  Any help would be greatly appreciated.

20

(16 replies, posted in Ruby on Rails)

Thank you Ryan!

I've started writing an FTP upload routine, but I'm getting Input/Output errors right now.  I'll work on it some more and see if I can't get it working.  If I can't get it working, I might just use extra mongrels and optimize Apache, but I'm sure I'll come across someone trying to upload a package of drawings, and those might exceed 2GB, so I think I'll have to get this working with FTP, or some other way.

The other thing I've been thinking about is using MERB.  Does anyone have any experience with MERB, and file uploads?

Thanks,
Zack

21

(16 replies, posted in Ruby on Rails)

They are now trying to upload architectural drawings... They can be up to 500 megs.

22

(16 replies, posted in Ruby on Rails)

I have an existing file management rails app that uses http for file upload (using attachment_fu).  The files that people are sending are getting too large for an http process.  Does anyone know how make these uploads instead go to our ftp server?

Thanks,
Zack

23

(1 replies, posted in Ruby on Rails)

Nevermind, I think this did it. But, I'd really like to DRY this code, if you have any input, please help.

	@sub_total =  @order.order_line_items.inject(0) do |sum, element| sum + ((element.quantity * element.unit_price))
	end
	if (@person.balance.to_i - @sub_total.to_i) > 0
	    @person.balance = (@person.balance.to_i - @sub_total.to_i)
	elsif ((@person.balance.to_i - @sub_total.to_i) < 0) and (@person.balance.to_i > 0)
        @person.balance = @person.balance.to_i - (((@sub_total.to_i - @person.balance.to_i) * 0.60) + @person.balance.to_i)	
	else ((@person.balance.to_i - @sub_total.to_i) < 0) and (@person.balance.to_i < 0)
		@person.balance = @person.balance.to_i - ((@sub_total.to_i) * 0.60)	
	end

24

(1 replies, posted in Ruby on Rails)

Hello,

I'm trying to keep track of dollars that employees spend on clothes, and I'm having a hard time get my discount to work.  Basically, each employee gets $150 to buy clothes a year at full catalog price.  Once they spend their $150, the money comes out of their paycheck, but they get a 40% discount off the catalog price.

This is what I have, but after the person gets into the negative(spending their own money), my calculation doesn't work correctly. 

        @order.order_line_items = @items
	@total =  @order.order_line_items.inject(0) do |sum, element| sum + ((element.quantity * element.unit_price))
	end
	if (@person.balance.to_i - @total.to_i) > 0
	    @person.balance = (@person.balance.to_i - @total.to_i)
	else (@person.ending_balance.to_i - @total.to_i) < 0
            @person.balance = @person.balance.to_i - (((@total.to_i - @person.balance.to_i) * 0.60) + @person.balance.to_i)	
	end

Any help you can provide will be greatly appreciated.

Thanks,
Zack

What if I didn't try to do this by reading the field name, but instead, the user could choose to "customize" their item, and have an ajax onclick div, that opens, revealing customization options, the user picks their options, clicks submit, that would pass the parameters back to the add_to_cart_ajax action, and not require me to try to pick out this value with Javascript? 

I ask only because I have a rough idea of how to accomplish this, but could use some ideas.

EDIT: I solved this by using a link_to_remote action, to open the form, and another link_to_remote action to capture the selections and submit to the cart.  This creates a seamless purchase for the buyer, and doesn't require any fancy Javascript, other than the link_to_remotes.

Thank you for your help ryenski