Rails getting activity feed that only involves current_user - ruby-on-rails

I'm using the public_activity gem on my rails app to get all of the current_users followers activity. It works great but I'd prefer to get only the activity that relates to the current_user so it's more of a Notification system than just Activities.
Here is what I have so far in my activities controller
#activities_all = PublicActivity::Activity.order("created_at desc").where(owner_type: "User", owner_id: current_user.followed_users.map {|u| u.id}).all
#activities = #activities_all.group_by { |t| t.created_at.beginning_of_day }
As stated before, this gives all the activities that the current_user's followers do (like create/comment on a post). I'd prefer it if I could get it to work where it's all the activities where my followers interact with my posts, etc. So when a user comments and that comment is on my post, then i want that to be part of #activities.
At first glance, I would figure this is another query I just cannot figure out the query (if query is the correct way).
Here is some front end code if that will help
<% #activities.sort.each do |day, activities| %>
<h6><%= day.strftime("%B %d") %></h6>
<% for activity in activities %>
<% if activity.trackable %>
<div class="activity">
<p>
<%= activity_user_image(activity.owner) %>
<%= activity_user_name(activity.owner) if activity.owner %>
<%= render_activity activity %>
<span><%= activity.created_at.strftime("%I:%M %p") %></span>
</p>
</div>
<% end %>
<% end %>
<% end %>
Thanks for the help all. Happy Holidays

In case anyone else have this question down the road, I found the answer
First, I added a recipient to each activity.
if #comment.save
#comment.create_activity :create, owner: current_user, recipient: #design.user
end
Then i added another query to the activities
#activities_all = PublicActivity::Activity.order("created_at desc").where(recipient_id: current_user).where("owner_id not in (?)", current_user).all

Not really sure about your relationships, but something like this should work:
#user_activities = PublicActivity::Activity.order("created_at desc").where(owner_type: "User", owner_id: current_user.id).all

Related

Listing users that voted on post using acts_as_votable

I'm trying to display the images of the users who've upvoted a post using the acts_as_votable gem, exactly like this question. The problem is the answer that worked for that question is not working in my case.
I display the upvotes count like this:
<%= #post.cached_votes_total %>
I've added 'acts_as_votable' and 'acts_as_voter' into the post and user models.
The controller:
def upvote
#post = Post.find params[:id]
#post.liked_by current_user
end
The accepted answer in the above question is this:
<% #post.votes_for.voters.each do |p| %>
<%= image_tag(p.image) %>
<% end %>
However this gives me an 'undefined method `votes_for' ' error.
<% #post.votes.each do |user| %>
<%= user %>
<% end %>
This gives no error but I can't access the user's image.
Ok, I got it by playing around a bit more.
<% #post.votes.by_type(User).voters.each do |user| %>

Rails - Unique Array in View

Having a Bit of trouble displaying unique results from my database. I have a database called "Activities". Each Activity has an associated Sport through sport_id. There may be many activities with the same sport_id.
I want to display a list of all sports linked to the activities database without displaying (for example "Football") twice.
FYI : Venues have many Facilities and Facilities have many Activities.
Controller:
#sports = Sport.all
#activities = Activity.paginate(page: params[:page])
#facilities = Facility.where(venue_id: #venue.id)
View:
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").each do |a| %>
<li><%= Sport.find(a.sport_id).name %>, (<%= a.facility_id %>)</li>
<% end %>
<% end %>
This shows:
Football, (2)
Hockey, (2)
Hockey, (2)
Football, (5)
I would like to display just:
Football
Hockey
Any ideas?
A simple solution would be to reduce your array with ruby in the view using: uniq!
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").uniq! { |a| a.sport_id }.each do |a| %>
<li><%= link_to Sport.find(a.sport_id).name, Sport.find(a.sport_id) %></li>
<% end %>
<% end %>
Another way may be to perform a single query on your DB since Sport what you want to narrow down
In controller:
#sports = Sport.joins(activities: [facility: :venue]).where(facilities: { venue_id: #venue.id }).distinct
In view:
<% #sports.each do |sport| %>
<li><%= link_to sport.name, sport %></li>
<% end %>
I am not sure about your DB schema so I went with what I thought you would have done, but it might needs some tweakings.
I hope I helped you.
try to use reject before each
<% #facilities.reject{your condition here}.each do |f| %>

RoR creating a form and passing back a hash

thanks in advance for looking at my issue. I'm new to programming and struggling with the concept of saving data to "foreign tables".
So this is a basic survey. I have a list of questions, that have answers belonging to it.
Here is my code that iterates through all the questions and answers:
<% #questions.each do |question| %>
<ul><%= question.questiondescription %></ul>
<% #answers = question.answers %>
<% #answers.each do |answer| %>
<li><%= answer.answerdescription %></li>
<% end %>
<% end %>
This works great. However I want all the answers to be radio buttons and store the selections in another table. I have another controller and table called "assessment_results". It looks like this:
User_Id, Assessment_Id, Question_ID, Answer_Id
I need to create a new record in this table for each question and answer. How would I go about doing this with having all the questions listed on one page?
So my thinking is I need a hash to push into that table for every question.
{[user_id:1, assessment_id:, question_id:1, answer_id:3]}
You could use the radio_button_tag and parse the results yourself.
Here is the breakdown
Looking at your assessment_results table I assume you have an Assessment controller based on the 'assessment_id' column.
Lets use that to present the questions.
Here is the assessments/new.html.erb
<h1>New assessment</h1>
<%= form_for(#assessment) do |f| %>
<% if #assessment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#assessment.errors.count, "error") %> prohibited this assessment from being saved:</h2>
<ul>
<% #assessment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<% #questions.each do |question| %>
<%= question.questiondescription %>
<ul>
<% #answers = question.answers %>
<% #answers.each do |answer| %>
<li><%= answer.answerdescription %><%= radio_button_tag("questions[#{question.id}]", answer.id) %></li>
<% end %>
</ul>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
So we have a standard assessment form that really just gives us the form structure and assessment button, we aren't going to actually use anything from it.
Best to build the view and then look at the source code in a browser.
The work is being done by the radio_button_tag, the first value "questions[#{question.id}]"
Will produce radio buttons with a name of "questions[1]" for the first group of questions and the value will be the answer id.
When rails sees a parameter like questions[1], it will put this into a hash called questions.
Here is the raw hash from the log when submitting the form with answers filled out:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lwqT5y+xUaYvt/GBObpN+BBO3F4YO8XaEGWcpS84lVw=", "questions"=>{"1"=>"2", "2"=>"8", "3"=>"13", "4"=>"18", "5"=>"23"}, "commit"=>"Create Assessment"}
The questions hash is:
"questions"=>{"1"=>"2", "2"=>"8", "3"=>"13", "4"=>"18", "5"=>"23"}
Now in the assessments controller, for the create method, I did the following:
def create
#assessment = Assessment.new(user_id: current_user.id)
respond_to do |format|
if #assessment.save
params[:questions].each do |question, answer|
AssessmentResult.create(user_id: current_user.id, assessment_id: #assessment.id,
question_id: question, answer_id: answer)
end
format.html { redirect_to #assessment, notice: 'Assessment was successfully created.' }
format.json { render :show, status: :created, location: #assessment }
else
format.html { render :new }
format.json { render json: #assessment.errors, status: :unprocessable_entity }
end
end
end
First we are creating an assessment that belongs to the user, I am assuming that you are using Devise or a similar system that uses the current_user for the current logged in user.
Next after saving with #assessment.save, this gives us our #assessment.id that the assessment results will belong to.
So the core work is happening here:
params[:questions].each do |question, answer|
AssessmentResult.create(user_id: current_user.id, assessment_id: #assessment.id
question_id: question, answer_id: answer)
end
end
params[:questions] - this is the params question hash that was submitted by the form.
params[:questions].each do |question, answer| - this takes the hash and for each, entry splits it into the key and value with |key, value|, in this case the key was the question id and the value was the chosen answer id.
Now we store the answer in the AssessmentResult model/table with the create command.
Say you now want to display the results of the assessment with: /assessments/1/show
def show
#assessment_results = AssessmentResult.where(assessment_id: #assessment.id)
end
Now you have the question and selected answer in the AssessmentResult
Make sure you set up your relations in the model:
app/models/assessment_result.rb
class AssessmentResult < ActiveRecord::Base
belongs_to :question
belongs_to :answer
end
Simple display of quesiton and selected answer, you will have to add the 'correct answer' code yourself.
app/views/assessments/show.html.erb
<% #assessment_results.each do |ar| %>
<%= ar.question.questiondescription %>: <%= ar.answer.answerdescription %>
<br />
<% end %>
Ok, when you have a nested models, here's what you can do
<%= form_for(#question) do |f| %>
<%= f.fields_for :answer do |ff| %>
<%= ff.label :image, 'Tag:' %>
<%= ff.checkbox :description, multiple: true, name: "answer[description]" %>
In your case, you have several answers belonging to some question, the principle is the same except you have to build specific ids for each answer, so I strongly suggest you these very helpful railscast
http://railscasts.com/episodes/197-nested-model-form-part-2
http://railscasts.com/episodes/75-complex-forms-part-3

Looping through a related model and comparing id's

The relation is that a user has many treatments and a treatment belong to user, one-to-many.
Now i want to print out all the users that have this particular treatment
Inside my treatments show view i have this double loop
<% User.all do |user| %>
<%= user.treatments.each do |t| %>
<% if (t.id).to_i == (#treatment.id).to_i %>
<%= link_to user.name, user_path(user) %><br />
<% end %>
<% end %>
<% end %>
if i change <% User.all do |user| %> to <%= User.all do |user| %> it prints out everything in my users table
can you guys spot why im not getting any users ?
i put a message in the beginning of the inner loop and it didnt display either, guess the problem is there but im not seeing it
.all returns an array. Array doesn't accept a block. Most likely, you want to do .each but forgot to write it. Try this:
<% User.all.each do |user| %>
but a better way is to not iterate all users like this, but get the correct list from the database directly.

Cannot manage associations in Ruby on Rails

I have a Post model which is used to store content posted by guest users, and that content is managed by an Admin user. The admin has the rights to block or unblock a particular post.
What I want to do is this:
Display all unblocked Posts to the Guest Users.
Display all Posts to the admin user.
For the first requirement, I have a model BlockedPost which has a polymorphic association with Post model. The post that will be blocked by the admin will be maintained in the BlockedPost model.
For the second requirement I have to give admin the right to block or unblock any particular content. So in my posts/index.html.erb I have done this
<% #posts.each do |post| %>
<% post.content %>
<% if post.post_blocked? %>
<td><%= link_to 'Unblock', blocked_post_path(content.id),:method => :delete%></td>
<% else %>
<td><%= link_to 'Block', create_blocked_post_path(content.id) %></td>
<% end %>
<% end %>
The post_blocked? method above is defined in the Post model:
class Post < ActiveRecord::Base
def post_blocked?
!self.blocked_posts.nil?
end
end
This works but the problem is every time the post_blocked? method is called it makes a database call.
Is there any way to stop this behavior and get the status of all posts in one database call itself?
hmm... i think you should change your models a little, because they are unconfortable a bit and there isnt any fast way to get your posts from DB,
delete BlockedPost model
and add a column to Post model (in migration)
t.boolean :blocked, :default => true
I'd do it like this:
#blocked_posts = Post.where( :blocked => false)
#unblocked_posts = Post.where( :blocked => true )
or prepare scopes in your Post model
and then in your view just display 2 lists
<% #unblocked_posts.each do |upost| %>
<%= upost.content %>
<%= link_to 'Block that post', ... %>
<% end %>
<% #blocked_posts.each do |bpost| %>
<%= bpost.content %>
<%= link_to 'Unblock', ... %>
<% end %>

Resources