Forum: Ruby on Rails wondering how to do some clever DRYing up

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F719c6cb34bd5b691c12b373b7244b4d?d=identicon&s=25 Dorian Mcfarland (tachekent)
on 2006-05-16 18:02
(Received via mailing list)
Hi there,
I'm now getting to the point in my rails app where I can use all of the
nice basic features like AJAX and engines etc...
but, I want to get my hands a bit dirtier, whilst learning to DRY up my
code a bit.

I'm using AJAX quite a bit to dynamically populate/edit/sort has_many
relationships in forms, and consequently on a model with many has_many's
I end up repeating functions to deal with adding, sorting & deleting
different types of record.

For instance I have the folllowing basic sorting controller method for a
sortable_element:

  def form_sort_performers
    i = 1
    params[:performers].each {
      |id|
      Performer.update(id, :position => i)
      i = i+1
    }
    render :nothing => true
  end


but, I have about 6 things that all need the same basic method
(Producers, ImagePersonnel etc...)
is there a way I can somehow move this into the application controller
and run it generically such that it takes a Model as an argument,
something like:

  def form_sort(model)
    i = 1
    params[:#{model}].each { # would need to pluralise
      |id|
      #{model}.update(id, :position => i)
      i = i+1
    }
    render :nothing => true
  end

I'm sure something like this is very possible, and most likely very neat
and easy to do in ruby/rails - I'm just not sure where to start!
any pointer gratefully recieved

thanks

dorian

--
I do things for love or money
D449d54c3b0f8c9930c11c7d7d3e6cdd?d=identicon&s=25 Surendra Singhi (Guest)
on 2006-05-16 20:19
(Received via mailing list)
Dorian Mcfarland <loaf@isness.org> writes:

>    params[:performers].each {
>  def form_sort(model)
> any pointer gratefully recieved
>

I also had a requirement (similar to yours), where I wanted to combine
the new
and create action functionality of many controllers into one, so I made
a base
controller class and made the other controllers classes inherit from it,
this
makes all the inherited controllers get the new and create action.

And for determining the model, I wrote a new model class which takes the
controller name, and then returns the equivalent model.

The same thing can be also done by a protected method in the application
controller, which is then called in other inherited controllers with the
model
class as an argument.

HTH.
--
Surendra Singhi
http://ssinghi.kreeti.com, http://www.kreeti.com
Read my blog at: http://cuttingtheredtape.blogspot.com/
,----
| "All animals are equal, but some animals are more equal than others."
|     -- Orwell, Animal Farm, 1945
`----
F719c6cb34bd5b691c12b373b7244b4d?d=identicon&s=25 Dorian Mcfarland (tachekent)
on 2006-05-17 03:47
(Received via mailing list)
I think I found an answer in the rails recipe book, the chapter "write
code that writes code", but thanks for the pointers.
9d1f5d2d9de70bd9a934f557dc95a406?d=identicon&s=25 Daniel ----- (liquid)
on 2006-05-17 04:54
(Received via mailing list)
There has been some talk on the Ruby-talk mailing list regarding getting
a
class from a name.

Thanx to Sergey Volkov for the class_by_name method.
Put this method into your application_controller.rb file to be able to
get a
class object from a string

def class_by_name name
   name.split("::").inject(Object){ |c,n|
       c.const_get(n)
   }
end

Then in whatever controller you want put in the following method (the
argument is either string or symbol)

This follows the convention that you have shown in your post regarding
the
pluralisation of the model name in the params hash as a symbol.

def form_sort( model )
  model = model.to_s
  params[model.pluralize.downcase.to_sym].each_with_index do |id,index|
    class_by_name( model.camelize ).update( id, :position => index )
  end
end

This isn't tested tho so fingers crossed.
This topic is locked and can not be replied to.