如果您已登录但不是该帐户的成员,我该如何执行 before_action 重定向

How can I do a before_action to redirect if you're signed in but not a member of the account

我正在尝试在我的控制器中创建一个 before_action,这样只有帐户中的成员(用户)才能查看和编辑与帐户相关的内容。目前,如果我在浏览器上更改 URL,我可以看到并编辑用户不是会员的帐户。

这是我的 discussion_controller:

    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

谢谢!

这是因为您没有限制访问,在控制器中创建新操作:

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

并称其为行动前的第一名:

before_action :restrict_access

当然你可以做任何你想做的事情而不是重定向也改变条件所以它会成为的成员。