Как я могу выполнить before_action для перенаправления, если вы вошли в систему, но не являетесь участником аккаунта - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь создать before_action в моем контроллере, чтобы только участники (пользователи) в учетной записи могли видеть и редактировать контент, связанный с учетной записью. В настоящее время, если я изменяю URL в браузере, я могу видеть и редактировать учетные записи, которые пользователь не является участником.

Это мой контроллер обсуждения:

    class DiscussionsController < ApplicationController
  before_action :set_discussion, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  # GET /discussions
  def index
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
    @pagy, @discussions = pagy(Discussion.joins(:posts).group('discussions.id').order('MAX(posts.created_at) DESC'))
  end

  # GET /discussions/1
  def show
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # GET /discussions/new
  def new
    @discussion = Discussion.new
    @discussion.posts.new
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # GET /discussions/1/edit
  def edit
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # POST /discussions
  def create
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
    @discussion = Discussion.new(discussion_params)
    @discussion.posts.each{ |post| post.user = current_user }

    if @discussion.save
      redirect_to @discussion, notice: 'Discussion was successfully created.'
    else
      render :new
    end
  end

  # PATCH/PUT /discussions/1
  def update
    if @discussion.update(discussion_params)
      redirect_to @discussion, notice: 'Discussion was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /discussions/1
  def destroy
    @discussion.destroy
    redirect_to discussions_url, notice: 'Discussion was successfully destroyed.'
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_discussion
      @discussion = current_account.discussions.find(params[:id])
    end


    # Only allow a trusted parameter "white list" through.
    def discussion_params
      params.require(:discussion).permit(:account_id, :user_id, :channel_id, :channel_name, :title, posts_attributes: [:body])
    end
end

и мои модели: Пользователь

class User < ApplicationRecord
  include ActionText::Attachable

  # Include default devise modules. Others available are:
  # :lockable, :timeoutable, andle :trackable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :confirmable, :invitable, :masqueradable,
         :omniauthable

  include UserAgreements, UserAccounts

  has_person_name

  include PgSearch::Model
  pg_search_scope :search_by_full_name, against: [:first_name, :last_name], using: { tsearch: { prefix: true } }

  # ActiveStorage Associations
  has_one_attached :avatar

  # Associations
  has_many :api_tokens, dependent: :destroy
  has_many :connected_accounts, dependent: :destroy
  has_many :discussions
  has_many :posts
  has_many :channels
  has_many :newactivitys, foreign_key: :recipient_id


  # We don't need users to confirm their email address on create,
  # just when they change it
  before_create :skip_confirmation!

  # Validations
  validates :name, presence: true
end

Обсуждение:

class Discussion < ApplicationRecord
  acts_as_tenant :account
  belongs_to :account
  has_many :posts, dependent: :destroy
  has_many :users, through: :posts

  belongs_to :channel

  scope :sorted, ->{ order(updated_at: :desc) }

  validates :title, presence: true

  accepts_nested_attributes_for :posts
end

И аккаунт:

    class Account < ApplicationRecord
  include Pay::Billable

  belongs_to :owner, class_name: "User"
  has_many :account_invitations, dependent: :destroy
  has_many :account_users, dependent: :destroy
  has_many :users, through: :account_users

  has_one_attached :logo

  scope :personal, ->{ where(personal: true) }
  scope :impersonal, ->{ where(personal: false) }

  has_one_attached :avatar

  validates :name, presence: true

  def email
    account_users.includes(:user).order(created_at: :asc).first.user.email
  end

  def personal_account_for?(user)
    personal? && owner_id == user.id
  end
end

Спасибо!

1 Ответ

4 голосов
/ 12 апреля 2020

Это потому, что вы не ограничиваете доступ, создаете новое действие в контроллере:

def restrict_access
  redirect_to root_path unless current_account.present? && current_account.discussions.pluck(:id).include?(params[:id])
end

и называете его первым местом перед действием:

before_action :restrict_access

конечно вы может делать все что угодно вместо перенаправления и изменить условие, чтобы оно стало членом.

...