I have a form where there can be three select boxes depending upon a checkbox - I'm using jQuery to show/hide them depending on which checkbox is active. Below, f is player
<% Game.all.each_with_index do |game, i| %>
<div class="team_<%= i %> hide">
<%= f.collection_select(:team_division_id, TeamDivision.where("game_id = ?", game.id),
:id, :name, include_blank: true) %>
</div>
<% end %>
Each collection select is generating an id of player_team_division_id - and since there can be only one id a page, this is really screwing with my results, namely the first select box shows up fine, but the others show up as simple links to javascript:void(0) - if I check out the generated divs with firebug/chrome, the information is there, it just isn't showing up as a select box (presumably) because of the id. I'm using chosen.js, if that makes a difference, although I'm don't think this has any affect.
Edit (Models):
class Player < ActiveRecord::Base
belongs_to :game
belongs_to :team_division, touch: true
end
class Game < ActiveRecord::Base
has_many :players
has_many :team_divisions
end
Class TeamDivision < ActiveRecord::Base
has_many :players
belongs_to :game
end
Related
I'm trying to render a nested form but the main problem is that the inputs generated haven't got a proper id/name. They should contain something like *_attributes but they don't.
Main model - Menu model
class Menu < ApplicationRecord
belongs_to :company
has_many :menu_days, :dependent => :destroy
accepts_nested_attributes_for :menu_days, allow_destroy: true, reject_if: :all_blank
has_and_belongs_to_many :dishes
has_and_belongs_to_many :locations
paginates_per 10
end
Nested model - MenuDay model
class MenuDay < ApplicationRecord
belongs_to :menu
validates :day, presence: true
end
New action in menus controller
def new
#menu = Menu.new
#frequencies = ##frequencies
##menu_days.each do |menu_day|
#menu.menu_days.build(:day => menu_day.day)
end
end
New.html.erb
<% menu.menu_days.each do |menu_day| %>
<%= f.fields_for :menu_days, menu_day do |menu_days_form| %>
<div>
<%= menu_days_form.check_box :day, class: "form-checkbox-nutri" %>
<%= menu_days_form.label :day, menu_day.day %>
</div>
<% end %>
<% end %>
This code is rendering the nested form, but the inputs code are something like this:
<div>
<input name="menu[menu_days][day]" type="hidden" value="0"><input class="form-checkbox-nutri" type="checkbox" value="1" name="menu[menu_days][day]" id="menu_menu_days_day">
<label for="menu_menu_days_day">Daily</label>
</div>
According to what I've read in the official documentation (https://guides.rubyonrails.org/form_helpers.html#building-complex-forms), names and ids should contain _attributes suffix. Besides, they should contain as well some kind of unique id. To sum up, they should be something like menu[menu_days_attributes][0][day]. But, as you can see, they're not.
Also I already tried with more basic fields_for implementations with same result. For instance (avoiding the external loop):
<%= f.fields_for :menu_days do |menu_days_form| %>
<div>
<%= menu_days_form.check_box :day, class: "form-checkbox-nutri" %>
<%= menu_days_form.label :day %>
</div>
<% end %>
In this case, it didn't even iterate properly and it only showed 1 block instead of 8.
What am I missing?
Thanks!
I'm a new guy to ruby on rails and working on my first in-depth application. It has four tables: Questions, Options, Answers and Users. There's a list of questions and a user can vote for a unique option (stored in the Answers join table), I'm trying to get my head around table associations.
This is how I've setup my individual RB files:
class Question < ActiveRecord::Base
has_many :options
has_many :answers, :through => :options
end
class Option < ActiveRecord::Base
belongs_to :question
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :user
belongs_to :question
belongs_to :option
end
class User < ActiveRecord::Base
has_many :answers
has_many :questions, :through => :answers
end
My questions controller is setup like this to include the options table:
#questions = Question.includes(:options).all
and the table body in my index.html.erb file:
<tbody>
<% #questions.each do |question| %>
<tr class="<%= cycle('lineOdd', 'lineEven') %>">
<td><%= question.question_text %></td>
<td><%= link_to 'Show', question %></td>
<td><%= link_to 'Edit', edit_question_path(question) %></td>
<td><%= link_to 'Destroy', question, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% question.options.each do |option_text| %>
<tr class="backgroundColor1">
<td class="optionCell"> <%= option_text.option_text %> </td>
</tr>
<% end %>
<% end %>
</tbody>
In the Question class I've used 'has_many :answers, :through => :options' - is this the correct way to go about this and how would I output the total number of votes in a table row below the associated option.
Do I need to add to or change the question controller code?
This is my first post, sorry if I'm not informative enough!
Thanks
Lets start by fixing up the relations a bit:
class Question < ActiveRecord::Base
has_many :options
has_many :answers
has_many :users, through: :answers
end
There is nothing technically wrong with has_many :answers, :through => :options but since there is a direct relation through answers.question_id we don't need to go through the options table for the relation.
Displaying the count
If we simply did:
<td class="optionCell"><%= option.answers.count %></td>
This would create a nasty n+1 query to fetch the count of the answers for each option. So what we want to do is create a counter cache which stores a tally on the options table.
Lets start by creating a migration to add the column:
rails g migration AddAnswerCounterCacheToOptions answers_count:integer
rake db:migrate
Then we tell ActiveRecord to update the tally when we create associated records, this looks a bit strange since the counter_cache: true declaration is on the belongs_to side while the column is on the other but thats just how AR works.
class Option < ActiveRecord::Base
belongs_to :question
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :user
belongs_to :question
belongs_to :option, counter_cache: true
end
There is a little snag here. Since we may already have records we need to make sure they have correct counters. You can do this from the console but in the long run it is a good idea to create a rake task.
Option.find_each { |option| Option.reset_counters(option.id, :answers) }
This might take a bit of time since it needs to pull each Option and update the count.
Now we can display the tally like so:
<% question.options.each do |option| %>
<tr class="backgroundColor1">
<td class="optionCell"><%= option.option_text %></td>
<td class="optionCell"><%= option.answers.size %></td>
</tr>
<% end %>
.size is smart enough to use our counter cache column, but will fall back to querying the count which is a good thing for tests.
I have a User table in Rails and it has 2 user types. I associated them with polymorphic associations, my models are:
class User < ActiveRecord::Base
belongs_to :owner, polymorphic: true
class Buyer < ActiveRecord::Base
has_one :user, as: :owner, dependent: :destroy
accepts_nested_attributes_for :user
class Seller < ActiveRecord::Base
has_one :user, as: :owner, dependent: :destroy
accepts_nested_attributes_for :user
I need a registration form in HTML for new users and automatically specify their type (each user type has their own registration link)
How do I manage the controllers and HTML form to do this? The user is going to fill the form with information for the User and Buyer or Seller model.
Thank you
You need 2 routes, one for buyer and another for seller. And then you can use Rail's form helpers:
<%= form_for :buyer do |f| %>
<%= f.fields_for :user %>
[your user fields here]
<% end %>
<% end %>
The form is analogous for the seller.
Im stuck (still very new to Rails), and cant figure out why its not working:
I have:
class Message < ActiveRecord::Base
attr_accessible :updated_at
has_many :categories_messages
has_many :categories, through: :categories_messages
end
class CategoriesMessage < ActiveRecord::Base
attr_accessible :category_id, :message_id
belongs_to :category
belongs_to :message
end
class Category < ActiveRecord::Base
attr_accessible :name
has_many :categories_messages
has_many :message, through: :categories_messages
end
#messagesPer = Category.all.includes(:messages).group('categories.id').order("COUNT(messages.id) DESC")
<% #messagesPer.each_with_index do |message, i| %>
<tr>
<td><%= i+1 %></td>
<td><%= message.name %></td>
<% if message.categories_messages.exists? %>
<td><%= message.messages.last.updated_at.to_s.to_date %></td>
<td><%= message.messages.first.updated_at.to_s.to_date %></td>
<td><%= message.messages.count %></td>
<% else %>
<td>0</td>
<td>0</td>
<% end %>
</tr>
<% end %>
So i want it to show :
the name of Category, date the last message was created , date first message was created, and all messages in that category.
ALl works fine, apart from the fact that it only shows the date when the first message was created, but never the last (still shows first date on the last).
What am i doing wrong?
UPDATE:
if i put
#messagesPer = Category.all.includes(:messages).group('categories.id')
it does show the right date for last and first messages but as soon as i add order it breaks...
I might be helpful to include the error information you get after adding an order clause to the query.
However, I can spot some odd things in the code. The CategoriesMessage model seems to be there simply to satisfy the condition that a category can have many messages and vice versa. You don't need a model for this many-to-many relationship though, Rails will handle this automatically for you.
Your models should be looking like this:
class Message < ActiveRecord::Base
attr_accessible :updated_at
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :messages
end
And in your database you have these tables: messages, categories,categories_messages, where the last one is the join table which only contains columns for amessage_idand acategory_id`.
Then you can simply do something like this in your code:
category.messages.each { |message| puts message.updated_at }
Also see this Ruby on Rails tutorial article for more information. If this doesn't work for you, please post the exact error you get.
I was hoping someone could help me with this, been trying to figure it out for a week now, I found a lot of examples, but as I'm new to rails I guess I keep making a mistake somewhere and I just cant find a right solution for my case.
So I have:
class Blog < ActiveRecord::Base
attr_accessible :name, :subject_id, :created_at
has_many :blogs_messages
has_many :messages, through: :blogs_messages
end
class Message < ActiveRecord::Base
attr_accessible :title, :body, :created_at
has_many :blogs_messages
has_many :blogs, through: :blogs_messages
end
class BlogsMessages < ActiveRecord::Base
attr_accessible :message_id, :blog_id
belongs_to :blog
belongs_to :message
end
Messages live in different Blogs(like Pink Blog, Green Blog, Maroon Blog etc), and Blogs live in Subjects (Dark Colors, Bright Colors etc)
Subjects have many Blogs, but Blogs can belong only to one Subject.
BlogsMessages is the connection between Messages and Blogs
what im trying to do is to show:
top 3 Blogs (by amount of messages in them) within one Subject
so e.g. when I want to choose Subject Dark Colors it will show me:
1.Maroon Blog: 46 messages
2.Grey Blog: 13 messages
3.Purple Blog: 12 messages
(There are 8 Blogs altogether in Subject Dark Colors.)
Could someone please help me with this, or at least point me in the right direction how to make it all work?
Update:
in my Blogs_controller now i have:
#blogs = Blog.joins(:blogs_messages => :message).select('blogs.*, COUNT(messages.id) AS message_count').group('blog_id').order('COUNT(messages.id) DESC').limit(3)
in my blogs view:
<% #blogs.each do |blog| %>
<li><%= blog.name %>: messages</li>
<% end %>
I'm not sure this can work because I can't test it but it may help you:
Blog.where(subject_id: subject.id)
.joins(:blogs_messages => :message)
.select('blogs.*, COUNT(messages.id) AS message_count')
.group(:blog_id)
.order('message_count DESC')
.limit(3)
Also, in the view you could access to the new virtual attribute message_count:
<% #blogs.each do |blog| %>
<li><%= blog.name %>: <%= blog.message_count %> messages</li>
<% end %>