Showing posts with label ruby-on-rails. Show all posts
Showing posts with label ruby-on-rails. Show all posts

Sunday, June 6, 2010

Paperclip Plugin Dependency for Ruby on Rails

Paperclip is an awesome plugin for Rails. There are already at least two great tutorials out there on the subject, but both neglect to mention installing the dependency ImageMagick. On a related note, how awesome has MacPorts become lately?



Install ImageMagick


Macintosh


If you have MacPorts installed...

sudo port install imagemagick


Debian/Ubuntu Linux


sudo apt-get install imagemagick


You can test everything installed okay with the which identify command. If it returns a location, you're good to go with these excellent tutorials:


Friday, March 19, 2010

When Regular Assignment Fails, update_attributes!...?

I've run into my second gotcha with Rails now, solved by the same function: update_attributes!. Both times it took me entirely too long to figure out.



I have a many-to-many assocation, whose proper model implementation is excellently described in the official guide. As expected, my join model :belongs_to each of the models in the many-to-many relationship. We have 3 models, all related to each other; 2 of them are related through the third:



Or, in code:


## in the Receipt class...
:belongs_to :store
:belongs_to :customer

## in the Store class..
:has_many :receipts
:has_many :customers, :through => :receipts

## in the Customer class...
:has_many :receipts
:has_many :stores, :through => :receipts



This ends up being really handy, because we can easily do things with collections owned by either a store or a customer:

@store.receipts.total_price.each do |r|...

Adapting this blog-building example from the Rails guides, led me to create a receipt while building on a store:

@receipt = @store.receipts.build(params[:receipt])

Being new at the time I wrote this code, I figured an easy-enough way to also determine customer ownership of receipts was to extend the assignments:

@receipt = @store.receipts.build(params[:receipt]) = @customer.receipts.build(params[:receipt])

Seems like it should work, but this throws undefined method `build=' errors. I promptly erased that last error-causing bit and headed back to the drawing board -- this time checking the server logs while executing a successful new/create operation. All of my attributes but customer_id were being passed.

Solution: change controller's create method to update the attributes (new portion in bold):


@receipt = @store.receipts.build(params[:receipt])
@receipt.update_attributes!(:customer_id => current_user.id)



Just like that, we're passing all attributes and everything in the @customer.receipts collection is working!



  • Note this does assume the excellent RESTful authentication plugin is being used and the user is logged in. Not a problem, since I don't expose my create method to users who aren't logged in, but worth noting nonetheless.

Monday, March 15, 2010

Rails Webapp: Closed Alpha Build

Ever want to use your webapp while it's still a closed alpha? Me too.


My solution is to only let people who have a passphrase create an account. Thanks to a suggestion by Rob125 in freenode's #RubyOnRails channel, I found the easiest way to do this was to modify 3 files.




  1. Create a constant in your Rails::Initializer.run do |config| method (config/environment.rb):

    Note you'll need to restart your app server for this to take effect.

    MY_SECRET_PHRASE = "econometrics is fun!"


  2. Add a textbox to your signup form (app/views/users/new.html.erb if using restful_authentication):

    <p>What's the passphrase?<br />
    <%= text_field_tag 'passphrase' %></p>


  3. Compare the constant to your parameter in the create method of the Users controller (app/controllers/users_controller.rb):

    @secret = params[:passphrase]
    if @secret == MY_SECRET_PHRASE then
      #all that successful stuff...
    else
      #all that flash[:error] stuff...



And there you have it. Easy to only allow access to a few a people while testing and easy to get rid of when it's time to truly go live. There is a drawback in the form of overhead that comes with an initializer, but certainly it's a fair tradeoff for a quick solution to a temporary problem.

Friday, March 12, 2010

Ubuntu Karmic 9.10 and ruby-pg

PostgreSQL, Ubuntu, and Rails seem exactly like a winning combination for the type of work I do.

As of this writing (March 12, 2010), the best driver to connect Rails and PostgreSQL is easily ruby-pg. My development environment is Snow Leopard, and my troubles installing ruby-pg on OS X were alleviated by this very helpful article at icoretech.

My server environment of choice is Ubuntu. Getting things up and running had me stumbling a bit again with the ruby-pg gem driver. Turns out the solution is simple -- just install the postgresql-server-dev-8.4 package and the gem installs fine.

The following steps will have PostgreSQL 8.4 and the ruby-pg driver up and running on your Ubuntu Karmic system (assuming you've already installed Ruby)

sudo apt-get install postgresql
sudo apt-get install postgresql-server-dev-8.4
sudo gem install pg