0

I have a Slider model in my project and it has a lot of polymorphic associations with other model like Product, Manufacturer, Article and etc.

So, when I use 'show' action with one of the models I also show related Slider. It's ok. But sometimes I need to show Slider with 'index' action.

What is the best way to link some of the sliders to actions, not to other models?

UPDATE

routes

resources :products, :articles, :industries, :manufacturers, only: [:index, :show]

Product controller

class ProductsController < ApplicationController

 load_resource

 # GET /products
 # GET /products.json
 def index
    @catalog = Product.by_type_and_manufacturer
 end

 # GET /products/1
 # GET /products/1.json
 def show
     @page_slider = @product.slider
 end
 end

So in 'show' action I just use product.slider to get related Slider instance. But I want to show another slider for all products by index action.

Grindel
  • 3
  • 4
  • Exactly what are you trying to accomplish here? Are you trying to show one Slider on the index for Sliders (this is the purpose of show, not index), or are you trying to show all Sliders? – Eddie Prislac Feb 05 '15 at 17:19
  • 1
    Code samples and a bit more of a fleshed out question will help you get more responses. As Eddie notes, it's not explicitly clear what you're trying to accomplish and with code, the more explicit you can be in your question, the better the responses/answers (and overall help) you'll get! – craig.kaminsky Feb 05 '15 at 17:21
  • Also, in the view of a rails app, links are usually going to be linked to controller actions (new_slider_path, edit_slider_path, etc...). What it looks like is you'd like to create a relation to a controller action, rather than to another model, is that correct? – Eddie Prislac Feb 05 '15 at 17:27

1 Answers1

0

In that case, what you're trying to do is not possible. You cannot create a relation to a controller action. What you need to do is link the relation's controller action, rather than trying to create a relation to the controller action. A model can only be related to another model (you cannot has_many index, show, delete, etc...)- In other words, call up the data for the relation, and link to that relation's controller action in the view.

example:

#Models:

class Page < ActiveRecord::Base
    has_many :sliders
end

class Slider < ActiveRecord::Base
    belongs_to :page
end

#Controllers

class PagesController < ApplicationController

    def index
        @pages = Page.all # lists all pages
    end

    def show
        @page = Page.find(params[:id]) # simplified, this will probably make use of strong params in your actual code
        @sliders = @page.sliders # all sliders related to the page
    end

   # if you would like to show a page that just has all sliders for a specific page and not the page itself...

   def show_page_sliders # you will have to create a route and view for this manually
        @page = Page.find(params[:id]) # simplified, this will probably make use of strong params in your actual code
        @sliders = @page.sliders # all sliders related to the page
        # note that this controller action is identical to the show action, because the data we're going to need is the same- the difference comes in the view
   end
end

class SlidersController < ApplicationController

    def index
        @sliders = Slider.all
    end

    def show
        @slider = Slider.find(params[:id])
    end

end


# Views
  # page#index
    <% @pages.each do |p| %>
      ...
      page listing code goes here. if you want to list the sliders for each page on the index...
    <% p.sliders.each do |s| %>
      ...
      individual slider info goes here
      ...
    <% end %>
    ...
   <% end %>

    # pages#show

   <%= @page.name %>
   <%= @page.content %> <!-- or whatever data you have for page -->
    # since here we are showing a singular page, we can just use our @page instance variable to list out the sliders
   <% @page.sliders do |s| %>
   ...
   Slider listing code goes here
   ...
   <% end %>


   # pages#show_sliders
   <!-- this is identical to the page#show view, minus the actual page info, and with the addition of a link back to the parent page -->
   <%= link_to "Back to page", page(s.page_id) %>

   <% @page.sliders do |s| %>
   ...
   Slider listing code goes here
   <!-- you can link to any path from the slider listing -->

   <%= link_to "Show", slider(s.id) %>
   <%= link_to "Edit", edit_slider_path(s.id) %>
   <%= link_to "Delete", delete_slider_path(s.id) %>
   ...
   <% end %>


#######################UPDATE#############################
# to define one slider per controller action
class PagesController < ApplicationController
def index
    @pages = Page.all
    # you need to add a "controller_action" column to your Slider model
    @slider = Slider.find_where(controller_action: "pages#index")
end

def show
    @page = Page.find(params[:id])
    @slider = Slider.find_where(controller_action: "pages#show")
end
# etc ...
Jai Chauhan
  • 4,035
  • 3
  • 36
  • 62
Eddie Prislac
  • 145
  • 1
  • 10
  • Thank you for the answer. Every Page has only one Slider. I know that I can't have a model relation to a controller or action. But I need some kind of it. For example I need a slider on the main page. Main page is "pages#index". So I need ability to get exact Slider in "pages#index" action. – Grindel Feb 05 '15 at 18:43
  • I've updated my code above with a solution. Unfortunately, rails does not provide for linking a specific record to another model's action, but you can implement it yourself simply by adding a 'controller_action' column with a unique value (ie: "pages#index") to your Slider model. – Eddie Prislac Feb 05 '15 at 19:18