RailsCasts Pro episodes are now free!

Learn more or hide this

Philipp's Profile

GitHub User: reqorder

Site: www.reqorder.com

Comments by Philipp

Avatar

The carrierwave-direct gem implements the key methods through calling mount_uploader in the painting model.

Avatar

UPDATE: You have to wrap the following code around the columns loop to get it working with migrations:

ruby
if self.table_exists?
  ...
end
Avatar

With the "server side solution" you can just pass your extra params through the path helper like this and the autocomplete jquery plugin will append them to the Ajax request:

_form.html.erb

ruby
<%= f.text_field :category_name, data: {autocomplete_source: categories_path(your_extra_param: 'value')} %>
Avatar

Great screencast. It helped me to DRY this problem a little bit up for SIMPLE model constellations as mentioned in this screencast.

Enclosed you'll just find an untested refactoring version but an older similar refactoring version has been tested successfully ;-)

So I would generally transform all tags with a data-autocomplete-source attribute into an autocomplete input.

application.js.coffee

ruby
jQuery ->
  $('[data-autocomplete-source*="auto"]').each (k, v) ->
    $(v).autocomplete
      source: $(v).attr('data-autocomplete-source')

This autocomplete data source can be put in a separate generic autocomplete action instead of the index action and be introduced to the client through a view helper:

application_helper.erb

ruby
module ApplicationHelper
  def autocomplete_input(f, field)
    f.input "#{field}_name", data: {autocomplete_source: eval("autocomplete_#{field.to_s.tableize}_path")}
  end
end

_form.html.erb

ruby
<%= autocomplete_input(f, :category) %>

routes.rb

ruby
resources :categories do
  collection do 
    get :autocomplete
  end
end

This module about a generic autocomplete action can be included at the top of every resource controller based on a ActiveRecord::Base child class (you have to set the autocomplete route for each controller as shown above):

ruby
module AutocompleteAction
  extend ActiveSupport::Concern
  
  def autocomplete
    render json: (
      request.path.split('/')[1, 2].first.classify.constantize.
      select(:name).order(:name).where("name LIKE ?", "%#{params[:term]}%").
      map(&:name)
    )
  end
end

The association setters could be generated dynamically through meta programming.

So the following code generates special setter methods for all belongs_to and polymorphic associations when included in an ActiveRecord::Base child class.

ruby
module AssociationSetter
  extend ActiveSupport::Concern

  included do              
    columns.map(&:name).select{|c| c.match('_id')}.each do |column|
      association = column.split('_id').first.classify
      
      define_method "#{association.underscore}_name" do
        self.send(association.underscore).try(:name)
      end
      
      accessible_attributes << "#{association.underscore}_name"
      
      define_method "#{association.underscore}_name=" do |name|
        return if name.blank?
        
        association_type = association
        
        if self.class.columns.map(&:name).include?("#{association.underscore}_type")
          association_type = self.send("#{association.underscore}_type")
        end
        
        self.send("#{association.underscore}=", association_type.constantize.find_or_initialize_by_name(name))
      end
    end
  end
end

P.S.: Maybe it turns out to be worth to extract in a gem some day ;-)