【问题标题】:How to require users to request group membership?如何要求用户请求组成员资格?
【发布时间】:2016-03-20 18:03:03
【问题描述】:

我有一个用户模型、一个组模型 (Cliq) 和一个 group_membership 模型 (Cliq_Membership)。到目前为止,一切似乎都运行良好。我目前拥有它,这样当用户创建一个组时,他们“拥有”它,而当“所有者”离开该组(破坏他们的组成员资格)时,整个组都被破坏了。一个组有一个所有者和许多成员。我想这样做,以便用户必须请求成为“成员”。我希望“所有者”是唯一可以看到请求并接受/拒绝请求的人。

为了清晰:

  • 我希望用户必须申请成为群组成员
  • 我希望 Cliqs 能够请求用户成为会员
  • 只有所有者才能查看/接受/拒绝好友请求
  • 我希望关系是“双向/自我参照”;也就是说,我希望将用户/成员显示为包含在该组中,并且该组具有另一个成员
  • Cliqs = 组

你是怎么做到的?

到目前为止,这是我的代码:

型号:

class User < ActiveRecord::Base
 has_many :uploads
 has_one :owned_cliq, foreign_key: 'owner_id', class_name: 'Cliq', dependent: :destroy

 has_many :cliq_memberships
 has_many :cliqs, through: :cliq_memberships
end

class CliqMembership < ActiveRecord::Base
 belongs_to :cliq
 belongs_to :user
end

class Cliq < ActiveRecord::Base
 belongs_to :owner, class_name: 'User'

 has_many :cliq_memberships, dependent: :destroy
 has_many :members, through: :cliq_memberships, source: :user

end

控制器:

class CliqMembershipsController < ApplicationController

def create
    #Cliq or Cliq_ID?
    @cliq = Cliq.find(params[:cliq])

    @cliq_membership = current_user.cliq_memberships.build(cliq: @cliq)
    @cliq.members << current_user

    if @cliq_membership.save
        flash[:notice] = "Joined #{@cliq.name}"
    else
        flash[:notice] = "Not able to join Cliq."
    end
    redirect_to cliq_url
end

def destroy
    @cliq_membership = current_user.cliq_memberships.find(params[:id])
    @cliq = @cliq_membership.cliq

    if @cliq.owner == current_user
       @cliq.destroy
       flash[:notice] = "Cliq has been deleted."
       redirect_to current_user
    else
    @cliq_membership.destroy
       flash[:notice] = "You left the Cliq."
    redirect_to current_user
    end
end
end

class CliqsController < ApplicationController

def show
    @cliq = Cliq.find(params[:id])
end

def new
    @cliq = Cliq.new(params[:id])
end

def create
    @cliq = current_user.build_owned_cliq(cliq_params)
    @cliq.members << current_user

    if @cliq.save
        redirect_to current_user
    else
        redirect_to new_cliq_path
    end
end

def destroy
    #@cliq = current_user.owned_cliq.find(params[:id])
    #lash[:alert] = "Are you sure you want to delete your Cliq? Your Cliq and all of its associations will be permanently deleted."
    #@cliq.destroy

    #if @cliq.destroy
       #redirect_to current_user
       #flash[:notice] = "You deleted the Cliq."
    #else
        #redirect_to current_user
        #set up error handler
        #flash[:notice] = "Failed to delete Cliq."
    #end
end


def cliq_params
    params.require(:cliq).permit(:name, :cliq_id)
end
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 activerecord associations


    【解决方案1】:

    您可以创建另一个模型和控制器来处理用户请求

    创建request.rb 模型

    class Request < ActiveRecord::Base
     belongs_to :user
     belongs_to :cliq
    end
    

    创建requests_controller.rb

    class RequestsController < ApplicationController
    
      before_action :set_group  
      before_action :auth_group_owner 
      before_action :find_request, except: [:index, :create]
    
      def index
      end
    
      def create
        @grp.requests.where(user_id: current_user.id).first_or_create
        # redirect the user
      end
    
      def approv
        # add the user to the group
        @request.destroy
        # redirect
      end
    
      def destroy
        #delete the request
      end
    
      private
    
      def set_group
        #find group @grp
      end
    
      def auth_group_owner
       if current_user != @grp.owner
        redirect
       end
      end
    
      def find_request
        #find request
      end
    
    end
    

    你的routes.rb

    resources :groups do
      resources :requests, only: [:index, :destroy] do
        member do
          get 'approv'
        end   
      end
    end
    

    【讨论】:

    • 如何创建(发送)请求?
    【解决方案2】:

    以下解决方案应该可以在不为请求创建新模型的情况下工作。向 CliqMembership 模型添加一个新的布尔字段来存储特定的 cliq_memberhip 是否被确认就足够了。 (例如,我们称该字段为“已确认”)

    class User < ActiveRecord::Base
      has_many :cliq_memberships
      has_many :cliqs, through: :cliq_memberships
      has_many :confirmed_memberships, -> { confirmed }, class_name: "CliqMembership"
      has_many :confirmed_cliqs, through: :confirmed_memberships, source: :cliq
    end
    
    class CliqMembership < ActiveRecord::Base
      belongs_to :cliq
      belongs_to :user
    
      scope :confirmed, -> { where(confirmed: true) }
    end
    
    class Cliq < ActiveRecord::Base
      has_many :cliq_memberships, dependent: :destroy
      has_many :members, through: :cliq_memberships, source: :user
      has_many :confirmed_memberships, { confirmed }, class_name: "CliqMembership"
      has_many :confirmed_members, through: :confirmed_memberships, source: :user
    end
    

    这样,当用户创建新的cliq_membership 时,您可以将confirmed 字段的值默认设置为false。直到所有者update 的那个特定cliq_membership 将confirmed 的值更改为true

    假设 usercliq 分别是 User 模型和 Cliq 模型的实例,您现在可以使用 user.confirmed_cliqscliq.confirmed_members

    编辑:

    为了将 cliq_membership 上的编辑和更新操作限制为仅限 cliq 所有者,您可以使用 before 过滤器

    class CliqMembershipsController < ApplicationController
      before_action :cliq_owner, only: [:edit, :update]
    
      def edit
        @cliq_membership = CliqMembership.find(params[:id])
      end
    
      def update
        @cliq_membership = CliqMembership.find(params[:id])
        @cliq_membership.update_attributes(cliq_membership_params)
      end
    
      private
        def cliq_membership_params
          params.require(:cliq_membership).permit(:cliq_id, :user_id, :confirmed)
        end
    
        def cliq_owner
          @cliq = CliqMembership.find(params[:id]).cliq
          redirect_to root_url unless @cliq.owner == current_user
        end
    end
    

    希望它对你有用。

    【讨论】:

    • 这似乎真的很接近我一直试图得到的。我应该如何更改我的控制器操作?以及如何从 Cliq/Cliq-Owner 向用户发送请求?
    • 您需要在CliqMembershipsController 中执行editupdate 操作才能将confirmed 字段从false 更新为true。我更新了答案以包括如何将权限限制为 cliq 所有者。
    • 这是有道理的。 Cliq 将如何向用户发送请求,让用户响应并加入 Cliq?
    • 您能举例说明更新/编辑控制器操作的外观吗?
    • 要向用户发送加入 cliq 的请求,所有者可以创建新的 cliq_membership 对象,其中包含他希望成为成员的用户的user_ids。然后在用户的仪表板/显示页面上,您可以向他们显示不同 cliq 所有者请求的 cliq_memberships。要跟踪这一点,您可能需要 CliqMembership 模型中的更多字段,就像您需要 confirmed 字段来跟踪成员资格确认一样。