Rails link_to polymorphic parent, which can have a nested route

Question!

I have the Comment model, which is polymorphic associated to commentable models like Project, User, Update etc. And I have a page where a user can see every User's comment. I want a link near each comment with an address of an object this comment is associated with. I could write something like that:

link_to 'show on page', Object.const_get(c.commentable_type).find(c.commentable_id)

But this will work only for not nested routes (like User). Here's how my routes look like:

resources :users do
  resources :projects, only: [:show, :edit, :update, :destroy]
end

So when I need a link to a Project page, I will get an error, because I need a link like user_project_path. How can I make Rails to generate a proper link? Somehow I have to find out if this object's route is nested or not and find a parent route for nested ones



Answers

You could use a bit of polymophic routing magic.

module CommentsHelper
  def path_to_commentable(commentable)
    resources = [commentable]
    resources.unshift(commentable.parent) if commentable.respond_to?(:parent)
    polymorpic_path(resources) 
  end

  def link_to_commentable(commentable)
     link_to(
       "Show # {commentable.class.model_name.human}",
       path_to_commentable(commentable)
     )
  end
end

class Project < ActiveRecord::Base
  # ...
  def parent
    user
  end
end

link_to_commentable(c.commentable)

But it feels dirty. Your model should not be aware of routing concerns.

But a better way to solve this may be to de-nest the routes.

Unless a resource is purely nested and does not make sense outside its parent context it is often better to employ a minimum of nesting and consider that resources may have different representations.

/users/:id/projects may show the projects belonging to a user. While /projects would display all the projects in the app.

Since each project has a unique identifier on its own we can route the individual routes without nesting:

GET /projects/:id - projects#show
PATCH /projects/:id - projects#update
DELETE /projects/:id - projects#destroy

This lets us use polymorphic routing without any knowledge of the "parent" resource and ofter leads to better API design.

Consider this example:

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  resources :projects

  resources :users do
    # will route to User::ProjectsController#index
    resources :projects, module: 'user', only: [:index]
  end

end

class ProjectsController < ApplicationController
  def index
    @projects = Project.all
  end
  # show, edit, etc
end

class User::ProjectsController < ApplicationController
  def index
    @user = User.joins(:projects).find(params[:user_id])
    @projects = @user.comments
  end
end

This would let us link to any project from a comment by:

link_to 'show on page', c.commentable

And any users projects by:

link_to "#{@user.name}'s projects", polymorpic_path(@user, :projects)
By : max


Make a Listview and then in its adapter add your table data. Make adapter's layout like this:

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2"            />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="*" />
   <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="=" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="4" />

By : VNS


If you are not going to be moving columns around (Friday will always be in whichever cell it is at present and days just continue in sequence to the right) it might be easier to select the entire range to be subject to formatting and HOME > Styles - Conditional Formatting, New Rule..., Use a formula to determine which cells to format and Format values where this formula is true::

=OR(MOD(COLUMN(),7)=3,MOD(COLUMN(),7)=4)  

Format..., select your choice of Fill, OK, OK.

Adjust 3 and 4 to match whichever day you choose to start the sequence with wherever your selected range starts.

Given information you have withheld of what is where the above might be simplified.

By : pnuts


This video can help you solving your question :)
By: admin