Rails: how to count number of users? - ruby-on-rails

here is my models.
User
unit_id
Unit
block_id
Block
postalcode_id
Postalcode
neighbourhood_id
Neighbourhood
name
the relations is for all is top belongs to bottom
this is my current index.html.erb file, i wish to output the number of user in each neighbourhood.
<% provide(:title, 'Neighbourhoods') %>
<ul class="thumbnails">
<% #neighbourhoods.each do |neighbourhood| %>
<li class="span3">
<div class="thumbnail">
<div style="position:relative;">
<%= link_to "Join", '#', class: "btn-join" %>
<%= image_tag(neighbourhood.name+".jpg", alt: neighbourhood.name) %>
</div>
<h2 style="margin-bottom:0px"><%= neighbourhood.name.titleize %></h2>
<% neighbourhood.postalcodes.each do |postalcode| %>
<%= postalcode.blocks.map(&:block).join(", ") %>
<% end %>
<br>
<%= neighbourhood.streetname.titleize %>
</div>
</li>
<% end %>
</ul>
Thanks in advance.

Assuming a Neighborhood has_many Users:
<%= neighbourhood.users.size %>
Note that counting is a relatively slow option, so you can optionally cache the number of users for speed using counter_cache:
class User < ActiveRecord::Base
belongs_to :neighborhood, :counter_cache => true
end
Then in a migration:
add_column :neighborhoods, :users_count, :integer, :default => 0

Seems like an awfully deeply nested set of associations. You may want to take a second look at your models and see if you can 'trim them down' a little. Maybe something like just have a User and Unit model, then add block, postal code and neighbourhood to Unit where you could do Unit.block, and Unit.postal_code...ect.
That being said with your current configuration (assuming correct associations of has_many/belongs_to) you should be able to do something like:
Neighbourhood.postal_code.block.unit.users.count
Good luck!

Related

Make shuffle order persistent across loops (Ruby on Rails)

I need to access the same random shuffling across two different loops on the same ERB page.
Context:
I have questions which have five choices of which one is TRUE for choices.is_correct.
My current ERB (below) successfully displays:
1) Grouped by usage
2) All available questions (shuffled)
3) And all five choices (also shuffled)
What I'd like to add is a separate loop (directly after in the same ERB), which gives:
1) Same grouping by usage
2) Same order of available questions (eg, same shuffle order)
3) The correct answer choice (eg, answer "B" = referencing the same shuffling)
Assigning the question or choice shuffling globally would not work, as I need it to be randomized on each page load.
Current ERB (currently shuffles each loop separately)
<%= #exam.name %>
<br />
<% alpha_numbers = ("A".."Z").to_a %>
<% #book_questions_by_usage.each do |usage, question| %>
<h4><%= usage if usage %></h4>
<% question.shuffle.each_with_index do |question, i| %>
<%= i+1 %>: <%= question.name %>
<ol type="A">
<% question.choices.shuffle.each_with_index do |choice, index| %>
<% choice.alpha_order = alpha_numbers[index] %>
<li><%= choice.name %></li>
<% end %><br />
</ol>
<% end %>
<% end %>
<% #book_questions_by_usage.sort.each do |usage, question| %>
<h4><%= usage if usage %></h4>
<% question.shuffle.each_with_index do |question, i| %>
<%= i+1 %>: <%= question.name %>
<ol type="A">
<% question.choices.select { |choice| choice.correct }.shuffle.each_with_index do |choice, index| %>
<% choice.alpha_order = alpha_numbers[index] %>
Correct Answer: <b><%= choice.alpha_order %>. <%= choice.name %></b>
<% end %><br />
</ol>
<% end %>
<% end %>
question.rb
class Question < ApplicationRecord
before_validation :assign_questionable
belongs_to :questionable, polymorphic: true
has_many :choices, :dependent => :destroy
accepts_nested_attributes_for :choices, allow_destroy: true
choice.rb
class Choice < ApplicationRecord
belongs_to :question
I've spent hours looking into possible solutions with no success so far. Any help is much appreciated!
How about you don't shuffle in the view, but in the controller. Save the shuffled array in an instance method and then use it in the view where you need it.

Trying to collect a list of ids from checkboxes to delete from my database

I'm creating an app (personal project) that'll help us schedule and record Nerf tournaments for a group I hang out with. I have tournament and player models. A tournament can have multiple players.
I want to be able to check multiple players and choose to delete them from the tournament. The thing is though is that all of my players are rendered in a nested partial. And my tournament partial has a form already inside of it.
Here is _tournament.html.erb:
<section class="panel" id="<%= dom_id(tournament) %>">
<h1 class="heading">
<%= tournament.name %>
</h1>
<ul>
<%= render tournament.players %>
</ul>
<section class="add_players">
<%= form_for [tournament, Player.new] do |f| %>
<div class="form-group">
<%= f.text_field :name %>
</div>
<div class="form-group">
<%= f.text_field :team %>
</div>
<%= f.submit "Add Player", class="button blue" %>
<% end %>
</section>
<section class="delete_all">
<button class="button red" type="button">Delete Players</button>
</section>
</section>
and here is _player.html.erb:
<li id="<%= dom_id(player) %>">
<div class="player">
<%= check_box_tag "player_ids[]", player.id %>
<span class="name"><%= player.name %></span> |
<span class="team"><%= player.team %></span>
</div>
</li>
I'm familiar with Railscast #52 where he does a simpler example of this, but I can't figure out how to get all of those checked checkboxes in the tournament partial and use those ID's to delete those players from the tournament.
I've tried wrapping the _tournament.html.erb partial inside of a form_tag but it breaks some styling (and HTML doesn't really allow that as a standard.)
Any guidance or help would be great!
What you are doing is creating a form that posts to /tournaments/:tournament_id/players which makes sense if you are assigning the players one by one or creating a single player.
It does not make sense at all if you are assigning multiple players to a tournament. Because you are actually changing the parent resource.
In that case you should be sending a POST request to /tournaments (to create a tournament) or a PATCH request to /tournaments/:id (to modify an existing record).
<%= form_for tournament do |f| %>
<div class="form-group">
<%= f.label :player_ids, "Assign players" %>
<%= f.collection_check_boxes :player_ids, Player.all, :id, :name %>
</div>
<%= f.submit %>
<% end %>
class TournamentsController < ApplicationController
# ...
private
def tournament_params
params.require(:tournament)
.permit(:foo, :bar, player_ids: [])
end
end
If you want to be able to create multiple player records in a single request you should use nested attributes and fields_for.
To unassign all the players you can do a PATCH request to /tournaments/:id
with an empty array as the value for tournaments[:players_ids]. You can do this with javascript by creating a handler that unchecks all the checkboxes and submits the form when the user clicks the button (or confirms it).
Or you could create a custom DELETE /tournaments/:tournament_id/players route.
resources :tournaments do
resources :players
delete :players, on: :collection, action: :delete_all_players
end

Displaying has_many, :through association records

I am working on an application a deep association. A Story belongs to a Planning Level, the Planning Level belongs to one or many Programs.
class Program < ActiveRecord::Base
has_and_belongs_to_many :planning_levels
has_many :stories, :through => :planning_levels
end
class PlanningLevelsPrograms < ActiveRecord::Base
end
class PlanningLevel < ActiveRecord::Base
has_and_belongs_to_many :programs
has_many :stories
end
class Story < ActiveRecord::Base
belongs_to :planning_level
end
Within the Program show page I'd like to display the Program, each Planning Level and aggregate Story count for each Planning Level.
I'm not sure how to access the Story model from the Program show page.
The following works great for displaying each Planning Level belonging to the Program.
<% #program.planning_levels.each do |p| %>
<p><%= p.name %></p>
<% end %>
...but I have no idea how to make the following work for each displayed Planning Level. How do I access the Story model from with the Program? Is there something needed in the Program controller that I'm missing. Thanks in advance!
#program.planning_level.stories.count(:id)
Each Planning Level:
<% #program.planning_levels.each do |planning_level| %>
<p><%= planning_level.name %></p>
# Aggregate Story count for each planning_level
<p><%= planning_level.stories.count %></p>
<% end %>
Aggregate Story count for #program (if you want):
#program.stories.count
Hope this can help you.
In your view, you can simply use the model associations by name to do this. Try this code as a starting point for your display needs:
<% #program.planning_levels.each do |planning_level| %>
<p><%= planning_level.name %> with <%= planning_level.stories.count %> stories</p>
<% planning_level.stories.each do |story| %>
<p><%= story.name %></p>
<% end %>
<% end %>
You can output any details that you choose for the stories loop. You can add styling to get the presentation that you need.
For instance, you might consider formatting this as a nested list, like so:
<% #program.planning_levels.each do |planning_level| %>
<ul>
<li>Planning Level: <%= planning_level.name %> with <%= planning_level.stories.count %> stories
<ul>
<% planning_level.stories.each do |story| %>
<li>Story: <%= story.name %></li>
<% end %>
</ul>
</li>
</ul>
<% end %>
Adding CSS class and id attributes would give you the ability to add styling to the elements to give your UI some flair.

Ruby - Is it possible to create two different loops in the same "view" file?

I'm currently learning Ruby on Rails thanks to a website named codecademy, and I'm learning how to display informations from a database's array stocked into a variable
The exercice's correction is as shown below :
<div class="main movie-show">
<div class="container">
<div class="movie">
<!-- Display the movie info here -->
<div class="info">
<%= image_tag #movie.image %>
<h3 class="movie-title"><%= #movie.title %></h3>
<p class="movie-release-year"><%= #movie.release_year %></p>
<p class="movie-plot"><%= #movie.plot %></p>
</div>
</div>
<h2>Cast</h2>
<% #actors.each do |actor| %>
<div class="actor">
<%= image_tag actor.image %>
<h3 class="actor-name"><%= actor.first_name %> <%= actor.last_name %></h3>
<p class="actor-bio"><%= actor.bio %></p>
</div>
<% end %>
</div>
</div>
You can see in the "movie" part that they directly take the variable to display the information needed, while they stock all the "actor" 's part in another |actor| variable
My question is the following, as I didn't find any satisfying answer online, is it possible to use two variables the same way in the same file ? Like using
<% #movies.each do |m| %>
and
<% #actors.each do |a| %>
Will it work anyway ? Will there be an error?
You can use as many number of instance variables as you want in your view provided that they are properly defined in your controller code.
If you have defined both #actors and #movies instance variables in your controller action, then you can access then them in corresponding view. Remember: I wrote, corresponding view.
There is other way as well. For example, if you have defined relation between your Movie model and your Actor model, and the relation states that a movie can have many actors. In that case, you only need to instantiate #movies in your controller, and then you can access actors in the following way:
<% #movies.each do |movie| %>
<% movie.actors.each do |actor| %>
<%# All other relevant code %>
<% end %>
<% end %>
In case, you don't know about relations, you can define them in following way:
class Movie < ActiveRecord::Base
has_many :actors
end
class Actor < ActiveRecord::Base
belongs_to :movie
# actors table should have a column named 'movie_id' for this to work
end

Rails: Dynamically created forms - how to accept answers for questions?

I have looked on the internet and stared at my screen for hours now and hope that you guys can help me out and can stop me from thinking in circles :) I've already found http://railscasts.com/episodes/196-nested-model-form-part-1 and http://railscasts.com/episodes/197-nested-model-form-part-2 but still can't get my mind around it...
Context
I'm trying to develop a CMS where users can create dynamic forms, with their own specific questions, question help text and possible answers (in case of radio buttons/checkboxes)
I am able to create the questions and the forms and to show the question in the viewer, my next step is to allow other users to answer the questions, but can't figure out how to do that.
What I have so far:
Form model:
has_many :custom_questions
has_many :custom_themes
has_many :form_submissions
has_many :answers
accepts_nested_attributes_for :answers
Question model
belongs_to :custom_form
belongs_to :custom_theme
has_many :possible_answers
accepts_nested_attributes_for :possible_answers
has_many :answers
accepts_nested_attributes_for :answers
Answer model
belongs_to :custom_questions
belongs_to :possible_answers
belongs_to :form_submissions
and the viewer which I use to load the questions and input fields:
<div class='content custom_forms clearfix'>
<%= form_for #customForm do |f| %>
<ul>
<%= #customForm.custom_themes.order(:order).each do |theme| %>
<div class='align_element'>
<section class='form_theme_title clearfix'><%= raw theme.theme_title %></section>
<section class="form_theme_description clearfix"><%= raw theme.theme_description.linkify %></section>
</div>
<ul class='selfce-reviews-table clearfix'>
<%= render "reviews/tabHeader" %>
<li class='row clearfix'>
<ul>
<li class="clearfix">
<% theme.custom_questions.order(:order).each do |question| %>
<li class='column selfc'>
</li>
<li class='column rev'>
<div class='align_element'>
<section class='form_question clearfix'>
<%= raw question.question %>
</section>
<section class="form_description clearfix">
<%= raw question.description.linkify %>
</section>
<%= f.fields_for question.answers.build do |builder| %>
<%= builder.hidden_field :custom_question_id, value: question.id %>
<% if question.q_type == "textfield" or question.q_type.nil? %>
<%= builder.text_field :answer, class:'reviews-inputBox clearfix' %>
<% elsif question.q_type == "textarea" %>
<%= builder.text_area :answer, class:'reviews-inputTextarea clearfix tinymce' %>
<%= tinymce %>
<% elsif question.q_type == "checkbox" %>
<% elsif question.q_type == "radio-button" %>
<% end %>
<% end %>
</div>
</li>
<% end %>
</li>
</ul>
<%= f.submit %>
</li>
<% end %>
</ul>
<% end %>
</div>
What I want is to store each answer in the table "answers" in the fields:
- question_id which refers to the unique id of the question
- answer - the value of the input field
As you can see I use #customForm which is the generated form by the administrator. I assume I use it here in the wrong way, because I don't want to update the form but only the answers... so instead it should be something like form_for :answers but that doesnt seem to work..
So my first question:
The way I see it every answer is unique and should therefore be seen as a unique form, hence my nested forms.. However if I use my code right now every input field has the same id: "custom_form_answer_answer". Is there a way I don't have to use nested forms to load the input fields for each question, e.g. by giving each answer a unique id based on the question_id?
I can't hardcode the inputfield name since this can change any time the user creates a new field..
My second question
If there is a way to do that.. how can I save the answers then..
Please let me know if you need any addition information.. and please keep in mind I'm fairly new to rails... so still learning!
Thanks! =-)

Resources