How to make private activities?

2020-04-18 07:46发布

问题:

How can we give the user the option to make activities private? This would give users privacy for posts they want for their eyes only.

Here was one of my attempts, which gives me:

NoMethodError in ActivitiesController#index undefined method 'public_activities' for line: @activities = Activity.public_activities.order("created_at desc").where(current_user.following_ids)

class ActivitiesController < ApplicationController
  def index #Added .public_activities
    @activities = Activity.public_activities.order("created_at desc").where(user_id: current_user.following_ids)
  end
end


class Activity < ActiveRecord::Base
  belongs_to :user
  has_many :comments, as: :commentable
  belongs_to :trackable, polymorphic: true

  def public?
    !private
  end
end

create_table "activities", force: true do |t|
  t.boolean "private", default: false
  t.integer  "user_id"
  t.string   "action"
  t.integer  "trackable_id"
  t.string   "trackable_type"
  t.datetime "created_at",     null: false
  t.datetime "updated_at",     null: false
end

class User < ActiveRecord::Base
  has_many :activities
  def public_activities
    activities.find(&:public?)
  end
end

And in one of the _forms, such as @valuations or @goals, is where the user can make the distinction via his submission:

 <%= button_tag(type: 'submit', class: "btn", id: "gold")  do %>
   <span class="glyphicon glyphicon-plus"></span> Public
 <% end %>

 <%= button_tag(type: 'submit', class: "btn") do %>
   <% :private %><span class="glyphicon glyphicon-plus"></span> Private
 <% end %>

Much of this code was inspired from the answer here: How to use private submit to hide from profile?

Thank you!

回答1:

class User < ActiveRecord::Base
  has_many :activities
  def public_activities
    activities.find(&:public?)
  end
end

This has defined a new instance method called public_activities - you will only be able to use it on an instance of a user

class ActivitiesController < ApplicationController
  def index #Added .public_activities
    @activities = Activity.public_activities.order("created_at desc").where(current_user.following_ids)
  end
end

Here you are trying to call a class method on the Activity class instead.

If you want to do the above, then you'll need to create a scope on the Activity class.

in which case, it's better not to repeat the "activities" part in the name, but just call it "public"

eg

class Activity < ActiveRecord::Base
  belongs_to :user
  has_many :comments, as: :commentable
  belongs_to :trackable, polymorphic: true

  scope :public, ->{ where(:private => false) }

  def public?
    private == true ? false : true
  end
end


class ActivitiesController < ApplicationController
  def index
    @activities = Activity.public.order("created_at desc").where(current_user.following_ids)
  end
end