How to use private submit with activities feed?

2019-06-24 04:40发布

问题:

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.

I was told this code isn't working because it might have something to do with "not setting up the 'private' checkbox to work correctly", yet the private checkbox works for hiding submissions on the public profiles (just not on the activities feed).

class ActivitiesController < ApplicationController
  def index #Added .public
    @activities = Activity.visible.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
  scope :visible, ->{ where(:hidden => false) }

  def visible?
    !hidden
  end
end

create_table "activities", force: true do |t|
  t.boolean "hidden", 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

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 %>
   <% :hidden %><span class="glyphicon glyphicon-plus"></span> Private
 <% end %>

Thank you!

回答1:

I would use an enum column instead. Enums give you tons of functionality such as scopes, interrogation and even bang methods to change the status. But most of all enums are built to extend - lets say you want to add the functionality that users can have posts that are only viewable by friends - adding an additional state to an enum is easy!

First we add a database column. Run:

rails g migration AddVisiblityToActivities visibility:integer:index

Then edit the migration to add a default:

class AddVisibilityToActivities < ActiveRecord::Migration
  def change
    t.integer :visibility, index: true, default: 0
  end
end

Run the migration with rake db:migrate. Then we need to add the enum mappings to the Activity model:

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

  # change the order if you want to default to private!
  enum visibility: [:visible, :hidden]

  default_scope { visible.order('created_at DESC') }
end

Note that we also add a default scope. With that we can really simplify the query in our controller:

class ActivitiesController < ApplicationController
  def index #Added .public
    @activities = Activity.where(user: current_user.following)
    # note that you don't have to use ids when creating a
    # where clause from an association. Rails does the work for you
  end
end

The easiest way to let users alter the visibility when creating/updating records is to use a select:

<div class="field">
  <%= f.label :visibility %>
  <%= f.select :visibility, Activity.visibilities.keys.map(&:titleize) %>
</div>

Just remember to whitelist the visibility property!

# app/controllers/activities_controller.rb

# ...

def create
  @activity = Activity.new(activity_params) do |a|
    a.user = current_user
  end

  # ...
end

# ...

def activity_params
  params.require(:activity).permit(:visibility)
end