we have models Articles , Photos and Events . And there is a model Comments . And I really want to keep all comments (comments of articles, photos and events) in one table.There are a lot of articles on this problem on the Internet, but there are also cases of “vice versa”. You don’t need to go far, let's try to develop the functionality of Habrahabr posts!
bash-3.2$ script/generate model post title:string published:boolean content_id:integer content_type:string
bash-3.2$ script/generate model topic body:text
bash-3.2$ script/generate model podcast link:string description:text
bash-3.2$ script/generate model link link:string description:textt.timestamps# app/models/post.rb <br/> class Post < ActiveRecord::Base <br/> belongs_to :content, :polymorphic => true , :dependent => :destroy<br/> end <br/> <br/> # app/models/topic.rb <br/> class Topic < ActiveRecord::Base <br/> has_one :post, :as => :content, :dependent => :destroy<br/> end <br/> <br/> # app/models/link.rb <br/> class Link < ActiveRecord::Base <br/> has_one :post, :as => :content, :dependent => :destroy<br/> end <br/> <br/> # app/models/podcast.rb <br/> class Podcast < ActiveRecord::Base <br/> has_one :post, :as => :content, :dependent => :destroy<br/> end <br/>:has_one :post, :as => contentbash-3.2$ script/console
>> t = Topic.new(:body => "Just one more test topic body here")
>> t.save
>> p = Post.new(:title => "Some test title", :published => true, :content => t)
>> p.save
>> Post.topics.new
=> #<Post id: nil, title: nil, published: nil, content_id: nil, content_type: "Topic", created_at: nil, updated_at: nil>>> Post.find_all_by_content_type("Topic")named_scope :topics, :conditions => { :content_type => "Topic" }<br/>named_scope :links, :conditions => { :content_type => "Link" }<br/>named_scope :podcasts, :conditions => { :content_type => "Podcast" } <br/>>> Post.topics
>> Post.links
>> Post.podcasts>> p.body
NoMethodError: undefined method `body' for #<Post:0x2653e00>
>> t.title
NoMethodError: undefined method `title' for #<Topic id: 8, body: "Just one more test topic body here">>> p.content.body
=> "Just one more test topic body here"
>> t.post.title
=> "Some test title"bash-3.2$ script/generate controller posts index
bash-3.2$ script/generate controller posts/topics index show
bash-3.2$ script/generate controller posts/podcasts index show
bash-3.2$ script/generate controller posts/links index show
bash-3.2$ script/generate controller home index
ActionController::Routing ::Routes.draw do |map|<br/> map.root :controller => 'home' <br/> <br/> map.namespace(:posts) do |post|<br/> post.resources :topics, :links, :podcasts<br/> end <br/> map.resources :posts<br/> <br/> map.connect ':controller/:action/:id' <br/> map.connect ':controller/:action/:id.:format' <br/> end <br/>And now let's start the server and see what we have: bash-3.2$ script/serverAnd we got this:/posts ( )
/posts/topics ( — –)
/posts/links ( — –)
/posts/podcasts ( , ;)# app/controllers/posts_controller.rb <br/> class PostsController < ApplicationController<br/> def index <br/> @posts = Post.find(:all)<br/> end <br/> end <br/> <br/> # app/controllers/posts/topics_controller.rb <br/> class Posts ::TopicsController < ApplicationController<br/> def index <br/> @posts = Post.topics.find(:all)<br/> end <br/> <br/> def show <br/> @post = Post.topics.find(params[:id])<br/> end <br/> end <br/> <br/> # app/controllers/posts/links_controller.rb <br/> class Posts ::LinksController < ApplicationController<br/> def index <br/> @posts = Post.links.find(:all)<br/> end <br/> <br/> def show <br/> @post = Post.links.find(params[:id])<br/> end <br/> end <br/> <br/> # app/controllers/posts/podcasts_controller.rb <br/> class Posts ::PodcastsController < ApplicationController<br/> def index <br/> @posts = Post.podcasts.find(:all)<br/> end <br/> <br/> def show <br/> @post = Post.podcasts.find(params[:id])<br/> end <br/> end <br/><!-- app/views/posts/index.html.erb --><br/><% @posts.each do |post| %><br/> <%= link_to post.content. class . to_s .pluralize, "/posts/#{post.content.class.to_s.downcase.pluralize}" %> →<br/> <%= link_to post.title, "/posts/#{post.content.class.to_s.downcase.pluralize}/#{post.id}" %><br/><br/><% end %> <br/>module PostsHelper<br/> def posts_smth_path (post)<br/> case post.content. class . to_s .downcase<br/> when "topic" : posts_topic_path(post)<br/> when "link" : posts_link_path(post)<br/> when "podcast" : posts_podcast_path(post)<br/> end <br/> end <br/> <br/> def posts_smths_path (post)<br/> case post.content. class . to_s .downcase<br/> when "topic" : posts_topics_path<br/> when "link" : posts_links_path<br/> when "podcast" : posts_podcasts_path<br/> end <br/> end <br/> end <br/><!-- app/views/posts/index.html.erb --><br/><% @posts.each do |post| %><br/> <%= link_to post.content. class . to_s .pluralize, posts_smths_path(post) %> →<br/> <%= link_to post.title, posts_smth_path(post) %><br/><br/><% end %> <br/><!-- app/views/posts/topics/index.html.erb --><br/><% @posts.each do |post| %><br/> <%= link_to post.title, posts_topic_path(post) %><br/><br/><% end %><br/>< p ><br/> <%= link_to "Add new Topic" , new_posts_topic_path %><br/></ p > <br/><h1><%= @post.title %></h1><br/><%= @post.content.body %> <br/><%= link_to "Add new Topic" , new_posts_topic_path %><!-- app/views/posts/topics/ new .html.erb --><br/><% form_for [:posts, @topic] do |form| %><br/> <% form .fields_for @post do | p | %> <br/> < p ><br/> <%= p .label :title %><br/><br/> <%= p .text_field :title %> <br/> </ p ><br/> < p ><br/> <%= p .check_box :published %><br/> <%= p .label :published %><br/> </ p ><br/> <% end %><br/> <br/> < p ><br/> <%= form .label :body %><br/><br/> <%= form .text_area :body %> <br/> </ p ><br/> <br/> < p ><%= form .submit "Create" %></ p ><br/><% end %> <br/>def new <br/> @topic = Topic. new <br/> @post = Post.topics. new <br/> end <br/>map.namespace(:posts) do |post|<br/> post.resources :topics, :links, :podcasts<br/> end <br/>def create <br/> @topic = Topic. new (:body => params[:topic][:body])<br/> if @topic.save<br/> @post = Post. new ({ :content => @topic }.merge params[:topic][:post])<br/> if @post.save<br/> redirect_to root_url<br/> else <br/> render :new<br/> end <br/> else <br/> render :new<br/> end <br/> end <br/>Source: https://habr.com/ru/post/79431/
All Articles