Search code examples
ruby-on-railsactivescaffold

What is the ActiveScaffold syntax for a 'has_many' relation link in list view if placed in the helper?


A 'product' has many 'parallel_products':

class Product < ActiveRecord::Base
  has_many :parallel_products, :class_name => "Product", :foreign_key => "master_product_id"
end

In the controller I add the 'parallel_products' column to the list view:

class ProductsController < ApplicationController
  active_scaffold :product do |config|
    config.list.columns = [ :parallel_products ]
  end
end

This gives me a ActiveScaffold generated link in the list view to view, create and edit parallel products of the selected product.

So far so good.

Now, I want to specify this 'parallel_products' link in the helper instead. No changes to the link itself, it should be exactly as the ActiveScaffold generated link. The reason is that I need to add a condition, so that the link is only shown under certain circumstances.

The ActiveScaffold generated link looks like this in the log:

Started GET "/products?assoc_id=6&association=parallel_products&eid=products_6_parallel_products&parent_scaffold=products&adapter=_list_inline_adapter" for 172.16.99.11 at 2012-03-05 09:37:45 +0100
  Processing by ProductsController#index as JS
  Parameters: {"assoc_id"=>"6", "association"=>"parallel_products", "eid"=>"products_6_parallel_products", "parent_scaffold"=>"products", "adapter"=>"_list_inline_adapter"}

My best proposal for the ActiveScaffold has_many relation link in the helper is:

link_to("link text", :controller => "products", :assoc_id => record.id, :association => "parallel_products", :eid => "products_#{record.id}_parallel_products", :parent_scaffold => "products", :adapter => "_list_inline_adapter")

This gives me in the log:

Started GET "/products?adapter=_list_inline_adapter&assoc_id=6&association=parallel_products&eid=products_6_parallel_products&parent_scaffold=products" for 172.16.99.11 at 2012-03-05 09:39:38 +0100
  Processing by ProductsController#index as HTML
  Parameters: {"adapter"=>"_list_inline_adapter", "assoc_id"=>"6", "association"=>"parallel_products", "eid"=>"products_6_parallel_products", "parent_scaffold"=>"products"}

My link does not work, but it seems to be very close. Only difference is that the generated link state 'ProductsController#index as JS' and my syntax state 'ProductsController#index as HTML'.

What is the correct ActiveScaffold syntax for making a 'has_many' relation list view link in the helper?


Solution

  • Thanks to Sergio Cambra for helping to solve this.

    This is the syntax for a 'has_many' association link if placed in the helper:

    link_to("link text", {:controller => "products", :association => "parallel_products",
      :parent_scaffold => "products", :product_id => record.id}, :class => 'index as_action',
      :id => "as_products-index-parallel_products-#{record.id}-link",
      :remote => true, :data => {:position => :after, :action => 'index'})
    

    To answer the question in full, this is how it can be implemented to exactly replace the autogenerated AS association link:

    def parallel_products_column(record)
      if product.parallel_products.blank?
        link_text = "-"
        css_class = "index as_action empty"
      else
        link_text = product.parallel_products[0...3].map{ |p| p.name }.join(", ")
        if product.parallel_products.length > 3
          link_text += ", &hellip; (#{product.parallel_products.length})"
        end
        css_class = "index as_action"
      end
      link_to(link_text.html_safe, {:controller => "products", :association => "parallel_products",
        :parent_scaffold => "products", :product_id => record.id}, :class => css_class,
        :id => "as_products-index-parallel_products-#{record.id}-link",
        :remote => true, :data => {:position => :after, :action => 'index'})
    end
    

    You will need a small 'hack' for the css 'empty' class, example:

    .active-scaffold a.empty {
      display: block;
      text-align: center;
    }
    

    Note: This is for Rails/AS 3.1 or newer.