2016-03-20 1 views
0

J'essaie de permettre aux utilisateurs de créer des projets ... et dès qu'un utilisateur crée un projet ... ils suivront automatiquement ce projet. (J'ai configuré mon application pour permettre à un utilisateur de suivre un projet à partir d'un bouton 'follow' sur le profil du projet). Je voudrais que le créateur du projet suive automatiquement le nouveau projet sans avoir à cliquer sur le bouton 'suivre'. J'ai réarrangé mon code selon la réponse de Bilal ... mais en cliquant sur 'créer un projet', je rafraîchis simplement la 'nouvelle' vue (aucun projet n'est posté). Je suppose cela a à voir avec les autorisations de Pundit, mais peut-être quelqu'un peut expliquer pourquoi le « créer » l'action ne fonctionne plus ...After_create relation suivante après la création du projet ne fonctionne pas

Mes projets Modèle:

class Project < ActiveRecord::Base 
    belongs_to :owner, :foreign_key=>'user_id', :class_name=>'User' 

    has_many :reverse_relationships, foreign_key: "followed_id", 
            class_name: "Relationship", 
            dependent: :destroy 
    has_many :followers, through: :reverse_relationships, source: :follower 

    validates :title, presence: true 
    validates :background, presence: true 
    validates :projectimage, presence: true 

    mount_uploader :projectimage, ProjectimageUploader 
    attr_accessor :crop_x, :crop_y, :crop_w, :crop_h 
    after_update :crop_projectimage 

    def crop_projectimage 
    projectimage.recreate_versions! if crop_x.present? 
    end 

    def private? 
    self.is_private == true 
    end 

    def public? 
    self.is_private == false 
    end 
end 

relations Modèle:

class Relationship < ActiveRecord::Base 
    belongs_to :follower, class_name: "User" 
    belongs_to :followed, class_name: "Project" 
    validates :follower_id, presence: true 
    validates :followed_id, presence: true 

    enum role: [:admin, :collaborator, :visitor] 
    after_initialize :set_default_role, :if => :new_record? 

    def set_default_role 
    self.role ||= :visitor 
    end 
end 

Mes projets contrôleur:

class ProjectsController < ApplicationController 
    before_filter :authenticate_user!, only: [:create, :new, :edit, :update, :delete, :followers] 

    # CREATES REDIRECT & ALERT MESSAGE WHEN PUNDIT SEES SOMEONE IS NOT AUTHORIZED (via :not_authorized_in_project below) 
    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 

    def new 
    @project = Project.new 
    end 

    def show 
    @project = Project.find(params[:id]) 
    authorize @project, :visit? 
    # @user = User.where(:id => @project.user_id).first 
    rescue Pundit::NotAuthorizedError 
    flash[:warning] = "You are not authorized to access this page." 
    redirect_to project_path || root_path 
    end 

    def index 
    @projects = policy_scope(Project).all 
    end 

    def create 
    @project = current_user.own_projects.build(project_params) 
    @project.followers << current_user 
    if @project.save 
     if params[:project][:projectimage].present? 
     render :crop 
     else 
     flash[:success] = "You've successfully created a Project..." 
     redirect_to @project 
     end 
    else 
     render 'new' 
    end 
    end 

    def update 
    @project = Project.find(params[:id]) 
    if @project.update_attributes(project_params) 
     if params[:project][:projectimage].present? 
     render :crop 
     else 
     flash[:success] = "Project Created" 
     redirect_to @project 
     end 
    else 
     render 'edit' 
    end 
    end 

    def destroy 
    User.find(params[:id]).destroy 
    flash[:success] = "Project destroyed" 
    redirect_to users_path 
    end 

    def followers 
    @title = "Following this Project" 
    @project = Project.find(params[:id]) 
    @project = @project.followers.paginate(page: params[:page]) 
    render 'show_follow_project' 
    end 

    private 

    def project_params 
    params.require(:project).permit(:title, :background, :is_private, :projectimage, :user_id, :crop_x, :crop_y, :crop_w, :crop_h) 
    end 

    def user_not_authorized 
    flash[:warning] = "You are not authorized to access this page." 
    redirect_to project_path(@project) || root_path 
    end 
end 

Mon modèle utilisateur:

class User < ActiveRecord::Base 
    has_many :own_projects, :class_name=>'Project' 

    has_many :projects 
    has_many :relationships, foreign_key: "follower_id", dependent: :destroy 

    has_many :followed_projects, through: :relationships, source: :followed 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    def following?(some_project) 
    relationships.find_by_followed_id(some_project.id) 
    end 

    def follow!(some_project) 
    self.relationships.create!(followed_id: some_project.id) 
    end 

    def unfollow!(some_project) 
    relationships.find_by_followed_id(some_project.id).destroy 
    end 

Politique projet Pundit:

class ProjectPolicy < Struct.new(:user, :project) 
    class Scope < Struct.new(:user, :scope) 
    # SCOPE & RESOLVE METHOD USED TO RESTRICT PROJECTS INDEX TO PUBLIC & THOSE YOU'RE AN ADMIN/COLLAB ON 
    def resolve 
     followed_project_ids = user.followed_projects.map(&:id) 
     public_project_ids = Project.where(:is_private=>false).map(&:id) 
     Project.where(:id=>followed_project_ids + public_project_ids) 
    end 
    end 

    def update? 
     user.project_admin? || user.project_collaborator? 
    end 


    # METHOD USED IN PROJECTS_CONTROLLER (SHOW) TO RESTRICT VISITING PRIVATE PROJECT PROFILES TO ADMINS & COLLABS 
    def visit? 
     user.project_admin?(project) || user.project_collaborator?(project) 
    end 

end 
+1

Essayez de réduire la casse lorsque vous postez des questions. Cette quantité de code est complètement inutile (il n'est pas nécessaire d'afficher le contrôleur/modèle WHOLE). – Waclock

+1

hah désolé homme - fera à l'avenir. Dans les publications précédentes, j'obtiendrais des réponses pour poster plus de code, alors j'ai pensé qu'il valait mieux en avoir trop plutôt que trop peu. (quand vous êtes un débutant, vous ne savez pas où vous pourriez parfois vous tromper) – BB500

Répondre

1

Il est jamais une bonne idée d'utiliser current_user dans un modèle, voir this pour référence.

Tout endroit facile et efficace pour régler cette chose serait le contrôleur lui-même. Ainsi, vous pouvez écrire le code suivant:

def create 
    @project = current_user.own_projects.build(project_params) 
    @project.followers << current_user 
    if @project.save 
    if params[:project][:projectimage].present? 
     render :crop 
    else 
     flash[:success] = "You've successfully created a Project..." 
     redirect_to @project 
    end 
    else 
    render 'new' 
    end 
end 
+0

Remerciez Bilal - mais en ajoutant cela (et en supprimant le after_create et la méthode du modèle), vous créez un problème en créant le projet. Il actualise simplement la "nouvelle" vue du projet et rien n'est créé. Je pense que c'est peut-être à cause de mes autorisations pundit? – BB500

+0

J'ai ajouté mon application_policy et la politique de projet de la gemme de pundit ... une idée de ce qui pourrait être à l'origine du problème? thx – BB500

+0

@ BB500 Pour cela, vous pouvez poser une autre question concernant la gemme 'pundit'. –