Rails: How to create polymorphic relationship/friendship model

假装没事ソ 提交于 2019-12-11 06:53:19

问题


I want to create a polymorphic friendship/network system.

For example

User can request or be requester to join multiple models like:

  • Company
  • Project
  • Group
  • Contacts(friends)

Some will be one to many e.g. a user is employed by one company but a company has many employees.

Others many to many e.g a user has many projects a project has many users

The relationships aren't to difficult to create using active recorded. The middle step, requesting(invitations) that has me baffled.

After bit of messing around this is what I came up with.

The example below will allow me to make requests from a profile(user) to a multiple models polymophically(Is that even a word?), including the profile model itself.

This is a sample of how the Controller could work.

@company = Company.find(params[:id])
@request = @company.requests.create!(status: "pending").build_profile 
@request.profile = current_user

How could I make @company more dynamic, say if it where a profile(user) requesting to join a project or a profile(user) requests to be friends with another profile(user)?

So I have solved this little problem I think with the following code in my controller.

requests_controller.rb

class RequestsController < ApplicationController
  before_filter :load_requestable

  def new
    @request = @requestable.requests.new
  end

  def create
    @request = @requestable.requests.new(params[:status])
  if @request.save
    redirect_to @requestable, notice: "Request sent."
  else
    render :new
  end
end

private

def load_resquestable
    resource, id = requests.path.split('/')[1, 2]
    @requestable = resource.singularize.classify.constantize.find(id)
end 

[sticking point] Now I'm trying to get the request button in my view happening and am getting the following error

undefined method `requests_path' for #<#<Class:0x007fe8b26667f8>:0x007fe8b26f40d0> 

Extracted source (around line #1):

1: <%= form_for [@requestsable, @request] do |f| %>
2:   <div class="field">
3:     <%= f.text_area :content, rows: 8 %>
4:   </div> 

Here is the code for the views

companies/show.html.erb

<%= @company.name %>
<% render 'requests/form' %>

requests/_form.html.erb

<%= form_for [@requestsable, @request] do |f| %>
  <div class="field">
    <%= f.text_area :content, rows: 8 %>
  </div>
  <div class="actions">
   <%= f.submit %>
  </div>
<% end %>

_models

profile.rb

class Profile < ActiveRecord::Base
  belongs_to :user
  belongs_to :company
  has_many :requests
  has_many :requested, as: :requestable

  attr_accessible :first_name, :last_name


  validates :first_name, presence: true
  validates :last_name, presence: true

end

request.rb

class Request < ActiveRecord::Base

   attr_accessible :status
   belongs_to :requestable , polymorphic: true
   belongs_to :profile

end

company.rb

class Company < ActiveRecord::Base
   has_many :employees, 
    :foreign_key => 'company_id', 
    :class_name => "Profile"

   has_many :requests, as: :requestable


  attr_accessible :name
  validates :name,  presence: true, length: { maximum: 50 }, uniqueness: true

end

回答1:


I think the it is not the User model that must be polymorphic.

What you can do is introduce another model UserRequest which will be a one to may association from User to UserRequest.

Then you can do the following:

class User < ActiveRecord::Base
  has_many :user_requests
  has_many :project_users
  has_many :projects, :through => :project_users
  has_many :group_users
  has_many :groups, :through => group_users
  has_many :contact_users
  has_many :contacts, :through => :contact_users
  belongs_to :company
end

And the RequestUser mdoel can keep a track of, what entities has a user requested for, also the RequestUser model will have a polymorphic association with Project, Company, Group and Contact models.

This way you can always have control over which user has request for which particular entity, and will also ease out the computations to be carried out.

Hope this architecture works for you. Let me know if you need any more assistance.

EDIT:

You can also implement a state change mechanism in the RequestUser model to check on the status of the request posted by a user.




回答2:


Yes of course AR supports polymorphic relations, and here's a link to RoR Guides.

http://guides.rubyonrails.org/association_basics.html



来源:https://stackoverflow.com/questions/11239486/rails-how-to-create-polymorphic-relationship-friendship-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!