Category Archives: Rails

oooh! Select me

Selects options have always been a mystery to me….  Here is an example that I got working.  The include_blank is pretty useful, it sets the value to “” and shows ‘none’

 =f.select :food,  ["burrito", "taco", "yums"], :selected => ("#{@my.foods.blank?}" || 'none' ), :include_blank => 'none'
24
Advertisements
Tagged

Active Record :dependent nullify fires before before_destroy

So, call backs are my friends but I got into some trouble with that.

Cats have many Arts.

Cats has nullify dependent and a before_destroy callback which runs a procedure on the Arts.

I got in a situation when Arts kept coming back nil, because the Cats get nil’d all over the place before the before_destroy callback happens.

params.merge

Great explanation
Links for extra parameters
Usually websites don’t expose all their searching/filtering capabilities as form. Usually there are some links, especially for changing category, ordering and other hard-to-input stuff. Creating links to the same page (action, controller, etc.) with the same extra parameters with just one (few) added or changed is extremely simple… just merge these new parameters!

link_to(“category 2”, params.merge({:category_id => 2}))
It exploits the fact that url_for (used with link_to’s second parameter) builds path from given hash and params hash is a magic one, containing also the controller, action and other extra stuff that’s been already input in the address bar

h = {“name” => “no”, “time” => Time.now} => {“name”=>”no”, “time”=>Fri Jul 08 11:59:44 -0700 2011} ruby-1.8.7-p334 :053 > h.merge(“big” => “mike”) => {“big”=>”mike”, “name”=>”no”, “time”=>Fri Jul 08 11:59:44 -0700 2011}

Keep in mind that params.merge does not modify params.  If you need to do this use: params.merge!

Running shell scripts from Inside Ruby Script

Use — exec “ls”

Pretty Print in the console:

 

y Model.all (y => to_yaml)

Use the rake

Here is how to write a rake that takes a commandline var.

 desc "test param passing"
    task(:test_my_params => :environment)  do 
      dir = ENV['dir'] #=> Here is how you pass a variable from the commandline.
      if File.exists?( File.expand_path "#{RAILS_ROOT}/data/dir1/#{dir}/Data.txt" )  #=> Check for a file 
        puts "FOUND IT"
      else
        puts "woops"
      end
    end

Check params always.

As a defensive technique it is always a good idea to check the params you are getting from a form submission before interacting with other services in the environment.

A best practice that I use is the following

if params[:thing] && params[:thing].size
       ....do this
     else
       ....do the thing with :thing
     end

Good Form

I have struggled with a form_for “situation” for about three days and want to post up the fruits of my labor so that it may save others (and myself) sometime incase this crops up again.

WARNING: This looks like a hack, because I kinda feel like it was.

First — Setting the stage in the controller so that form_for will work properly:

https://github.com/ridingwithrails/monkey/commit/9fb37995f9550a00e258bf8eda3f4533c7372bc1#diff-0

Second — View with some logic in order to detect edit or new
https://github.com/ridingwithrails/monkey/blob/9fb37995f9550a00e258bf8eda3f4533c7372bc1/app/views/today/_task.html.erb

Great reference: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

Sexy Validation

Recently I ran into the issue below (taken from a post on stackoverflow)

have a couple of simple models that are associated like so:

MODELS

class Task < ActiveRecord::Base
  belongs_to :user
  validates :name, :presence => true ,  :message => 'Name cannot be blank, Task not saved'


end


class User < ActiveRecord::Base has_many :tasks


end

VIEW has a call in it like so: user.tasks true , :message => ‘Name cannot be blank, Task not saved’

I get a 500 error: ActionView::Template::Error (uninitialized constant User::Task): NameError in View file

when I use:

validates_presence_of :name

Everything works.

I thought the both validates methods above where the same…is the issue have to do with associations and how validation tie into associated models. I have a hunch that something is going on with the way things are associated, but it is just a hunch.

The solution:
When you use the newer validates :name format, you can put multiple validations in one line rather than having to have multiple lines for each type of validation. Because of this, when Rails hits your :message parameter, it thinks it’s a validation method rather than a message associated with :presence. Try this instead:

validates :name, :presence => {:message => 'Name cannot be blank, Task not saved'}

Also, depending on how you display your errors, this error may actually show up as ‘Name Name cannot be….’; if so, you’ll want to set the message to just ‘cannot be blank, Task not saved’.

original post: http://stackoverflow.com/questions/5078990/validates-presence-vs-validates-presence-of-using-rails-3
solution by : http://www.dylanmarkow.com/

Basically, unless something is a validation use {}

Adding some Basic Ajax Elements (not using Jquery…yet)

Use of Drag and Drop in order to re order a list. In the background I added acts_as_list functionality.

On the page where the list appears add the following code to the near the very bottom before < /body >

sort_url , :complete => visual_effect(:highlight, 'todo-list')%>

Notes:
* The element is the name of the UL;
* Set up sort_url in the routes file to point to the correct sort method in the controller
* The sortable_element tag should work right out of the box.

Use RJS to capture simple and small changes on page. An Example of this is below:

In the partial add:
#_todo.html.erb
"Mark Complete"), complete_url(:id => todo.task.id), :remote => true%>

Notes:
link_to_remote is gone and so I am using :remote => true .

Update the controller so that the page is not redirected in an unexpected way, for example I had to kill

redirect_to root_path From the action that was handling this.

Next, add the appropriate rjs file to handle the returning of the js code back to the page.

1) Create an rjs file (name it following the action in the controller)

2) In the rjs file specify the behavior … for example:

page.replace_html 'todo-list', :partial => '/today/todo', :collection => @todos # Put partial here
page.visual_effect :highlight, 'todo-list' #todo-list is the name of the ul
page.sortable 'todo-list', :url => sort_url #call the method

Toggle a Form
Add style=”display:none;” to the div tag that wraps the render partial tag.

Add snippet of code inline (directly above the div tag mentioned above:

Riding the Routes

Rails 3 has made massive changes to routes. Gone are the send-as-hash days:

link_to image_tag('arrow_left.gif',
:title => 'Do Today'),
:controller => 'todo',
:action => 'create',
:id => task.id

Did not work. Got one routing error after another.

Finally I read pages 31 to 54 in the Rails 3 way. Then after some experimentation I arrived at

#routes.rb file
match '/todo/:id/create', :to => 'todo#create', :as => :create

Basically says create a url in the following manner everytime you see create_path (code from view below)
pattern /todo/1/create and route over to the action create in the todo controller.

#in the view.html.erb
"Do Today"), create_url(:id => task.id) %>
#both create_url and create_path worked for me

 

:member expects an :ID => It thinks you have an instance already.

:collection expects a list => It will hit controller and list (index and list views).