一个模型上的多个多态属性

时间:2014-05-22 21:27:54

标签: ruby-on-rails comments polymorphic-associations

我一直在创建一个应用程序,它有几种不同的模型类型,可以作为不同的页面类型。 我目前有一个Posts模型,有两个多态属性:Postable和Posterable,这些是发布帖子的页面,以及每个帖子的作者。
例如,我希望用户能够创作和接收帖子,同时我还希望群组能够通过管理员用户接收帖子和作者。

My Post模型目前如下:

class Post < ActiveRecord::Base
before_create :set_latlong

belongs_to :posterable, polymorphic: true
    belongs_to :postable, polymorphic: true

default_scope -> { order('created_at DESC') }
validates :content, presence: true, length: { maximum: 140 }
validates :posterable_id, presence: true
validates :posterable_type, presence: true

def set_latlong
    self.latitude = posterable.latitude
    self.longitude = posterable.longitude
end

def self.from_users_favourited_by(user)
    favourited_user_ids = "SELECT favourite_id FROM favouriteusers
                                WHERE favourited_id = :user_id"
    where("posterable_id IN (#{favourited_user_ids}) OR posterable_id = :user_id", user_id: user.id)
end

发布计划是:

  create_table "posts", force: true do |t|
t.string   "content"
t.integer  "posterable_id"
t.string   "posterable_type"
t.float    "latitude"
t.float    "longitude"
t.integer  "postable_id"
t.string   "postable_type"
t.datetime "created_at"
t.datetime "updated_at"

我相信这些都是可行的,允许各种模型在各种模型页面上发布。但是,我还不太确定如何实现这一点,Post控制器如下:

class PostssController < ApplicationController

before_action:authenticate_user!,only:[:create,:destroy]   before_filter:load_posterable

def new     @post = Post.new(post_params)   端

def创建     @posterable = load_posterable     @post = @ posterable.posts.build(post_params)     @ post.postable = find_postable     if @ post.save         flash [:success] =&#34;发布后!&#34;         redirect_to root_url     其他       @feed_items = []         渲染&#39; static_pages / home&#39;     结束   端

def def     @post = Post.find(params [:id])     if @ post.present?       @ post.destroy     结束     redirect_to root_url   端

私有

def post_params
    params.require(:post).permit(:content)
end

def load_posterable
  resource, id = request.path.split('/')[1, 2]
  resource_name = resource.singularize.classify
  if resource_name = "user"
    @posterable = current_user
  else 
    @posterable = resource_name.constantize.find(id)
  end
end

def find_postable
  resource, id = request.path.split('/')[1, 2]
  resource_name = resource.singularize.classify
end

我认为做这项工作的关键是分离&#34;资源&#34;在load_posterable和find_postable方法中,我从Railscast教程中获得了多态关联,但我真的不知道如何在同一模型中区分它们?

1 个答案:

答案 0 :(得分:0)

好的,所以你需要一个Profile模型,用户/管理员将使用该模型在网站上进行操作。

您应该为用户自动创建并选择它(默认为一个),然后为每个组分别设置一个成为管理员。

配置文件本身不应该包含任何属性,只需将它们通过关联(如果您愿意,可以是多态的)委托给用户或其他模型。

这样你就拥有了一个非常干净的界面,Profile类将成为你模特的装饰者。

在控制器级别,您应该在Devise中使用类似于current_profile的{​​{1}}方法,该方法将存储/检索会话中的个人资料ID。

请参阅:http://en.wikipedia.org/wiki/Decorator_pattern