Show images grouped by their FK id - ruby-on-rails

I have the following setup so far using Rails 4
class Tournament < ActiveRecord::Base
has_many :fixtures
has_one :gallery
has_many :gallery_images, :through => :gallery
end
class Gallery < ActiveRecord::Base
belongs_to :tournament
has_many :gallery_images, dependent: :destroy
accepts_nested_attributes_for :gallery_images, allow_destroy: :true
end
class GalleryImage < ActiveRecord::Base
belongs_to :gallery
end
With my db setup like so
create_table "galleries", force: true do |t|
t.integer "tournament_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "gallery_images", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.string "photo_file_name"
t.string "photo_content_type"
t.integer "photo_file_size"
t.datetime "photo_updated_at"
t.integer "gallery_id"
end
create_table "tournaments", force: true do |t|
t.string "name"
t.date "tourn_date"
t.string "tourn_location"
t.datetime "created_at"
t.datetime "updated_at"
end
I am trying to get a gallery and all its images into an object so that i can iterate through all the gallery_images by each tournament
<div id="verticalTab">
<ul class="resp-tabs-list">
<% #tournaments.each do |t| %>
<li><%= t.name %></li>
<% end %>
</ul>
<div class="resp-tabs-container">
<div>
<% #tournaments.each do |t| %>
<div class="clear"></div>
<% g.gallery_images.each do |i| %>
<ul class="team-gallery">
<li><%= image_tag(i.photo.url(:gallery_image)) %></li>
<% end %>
</ul>
<% end %>
Controller
def index
#tournaments = Tournament.all
end
Im a little unsure on how to group gallery_images by its tournament
Any pointers appreciated

try something like this for your tournament model
class Tournament < ActiveRecord::Base
has_many :fixtures
has_one :gallery
has_many :gallery_images, through: :gallery
end
then in your view you could do something like
<ul class="resp-tabs-list">
<% #tournaments.each do |t| %>
<li><%= t.name %></li>
<% t.gallery_images.each do |img| %>
<% end %>
<% end %>
</ul>
or alternatively you could do something like this as roman.brodetski commented which would not require you to modify your model
<ul class="resp-tabs-list">
<% #tournaments.each do |t| %>
<li><%= t.name %></li>
<% t.gallery.gallery_images.each do |img| %>
<% end %>
<% end %>
</ul>
(note that your controller variable name #tournaments didn't agree with the one you were referencing in the view and would have been nil as a result)
One other thing to note is that your models Tournament and Gallery are one to one and I think what you may want given your question is that Tournament and Gallery be a one to many relationship, in which case your Tournament model should look like
class Tournament < ActiveRecord::Base
has_many :fixtures
has_many :galleries
end
in which case you could have your view do something like
<ul class="resp-tabs-list">
<% #tournaments.each do |t| %>
<li><%= t.name %></li>
<% t.galleries.map{|a| a.gallery_images}.flatten.each do |img| %>
<% end %>
<% end %>
</ul>

Related

No Method Error - Getting Name from Table

I have an agent and an agent_review model and I am trying to create a page where all of the reviews are accessible on the same page. I am having an issue pulling out the agent who is being reviewed and the reviewer's name.
ERB:
<div class="mega-container">
<%= render 'matrix/listings/matrix_navigation' %>
<div class="standard-page-header">
<h1>Agent Reviews</h1><br>
<hr>
</div>
<div class="text-center">
<div class="container feedback-index">
<% #agent_reviews.each do |agent_review| %>
<div class="row feedback-strip">
<h3>Agent Name: <%= agent_review.agent.name %></h3>
<p>Review: <%= agent_review.comment %></p>
<p>Star Rating: <%= agent_review.rating %> of 5</p>
<p>Reviewer: <%= agent_review.reviewer.name %></p>
<p>Submitted: <%= agent_review.created_at.strftime('%D # %l:%M%p') %></p>
</div>
<% end %>
</div>
</div>
</div>
Schema:
create_table "agent_reviews", force: :cascade do |t|
t.integer "agent_id"
t.integer "reviewer_id"
t.text "comment"
t.integer "rating"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Controller:
def all_reviews
#agent_reviews = AgentReview.all
end
Models:
class Agent < ActiveRecord::Base
has_many :agent_reviews
end
class AgentReview < ActiveRecord::Base
belongs_to :agent, foreign_key: 'reviewer_id'
end
In your AgentReview model:
belongs_to :reviewer, :class_name => 'Agent', :foreign_key => 'reviewer_id'
belongs_to :agent, :class_name => 'Agent', :foreign_key => 'agent_id'
It looks like you're missing an association on AgentReview
class AgentReview < ActiveRecord::Base
belongs_to :reviewer, class_name: "Agent", foreign_key: 'reviewer_id'
belongs_to :agent
end

How to get data in has_many :through association?

I'm following this tutorial and this tutorial to learn more about has_many :through association in Rails. I created an app called school. And I have this inside my schema.rb file:
create_table "courses", force: :cascade do |t|
t.integer "teacher_id"
t.integer "student_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "quantity"
end
create_table "students", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "teachers", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
My teacher model:
class Teacher < ActiveRecord::Base
has_many :courses
has_many :students, :through => :courses
end
My student model:
class Student < ActiveRecord::Base
has_many :courses
has_many :teachers, :through => :courses
end
My course model:
class Course < ActiveRecord::Base
belongs_to :teacher
belongs_to :student
end
And my /courses view now looks something like this (I'm using scaffold):
When I go to /teachers/1, I want to display all students name and quantity associated with that teacher.
The current view of /teachers/1 is like this:
I try to make it by using this code but it's not working:
<% #course.each do |c| %>
<p><%= c.quantity %></p>
<% end %>
So, how to display all students name and quantity associated with that teacher?
<% #teacher.courses.each do |c| %>
<p><%= c.student.name %></p>
<p><%= c.quantity %></p>
<% end %>
You have to use the name of relation on variable with teacher object.
<% #teacher.courses.each do |c| %>
<%= c.quantity %>
<% end %>
<% #teacher.students.each do |s| %>
<%= s.name %>
<% end %>
Solved with this code:
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #teacher.name %>
</p>
<table>
<tr>
<th>Student Name</th>
<th>Quantity</th>
</tr>
<% #teacher.courses.each do |c| %>
<tr>
<td><%= c.student.name %></td>
<td><%= c.quantity %></td>
</tr>
<% end %>
</table>
<%= link_to 'Edit', edit_teacher_path(#teacher) %> |
<%= link_to 'Back', teachers_path %>
Thanks to msergeant and Jan!

How to set up a form to create several records on a has_many :through join table?

I'm trying to create a form that creates a new exercise with muscle_groups that are primary and secondary to the exercise.
Here's the relevant part of the schema:
create_table "exercised_muscle_groups", force: true do |t|
t.integer "muscle_group_id"
t.integer "exercise_id"
t.string "used_as"
end
add_index "exercised_muscle_groups", ["exercise_id"], name: "index_exercised_muscle_groups_on_exercise_id", using: :btree
add_index "exercised_muscle_groups", ["muscle_group_id"], name: "index_exercised_muscle_groups_on_muscle_group_id", using: :btree
create_table "exercises", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "muscle_groups", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
Here's what I have for the models:
class Exercise < ActiveRecord::Base
has_many :exercised_muscle_groups, dependent: :destroy
has_many :muscle_groups, through: :exercised_muscle_groups
accepts_nested_attributes_for :muscle_groups
accepts_nested_attributes_for :exercised_muscle_groups
end
class MuscleGroup < ActiveRecord::Base
has_many :exercised_muscle_groups
has_many :exercises, through: :exercised_muscle_groups
accepts_nested_attributes_for :exercises
accepts_nested_attributes_for :exercised_muscle_groups
end
class ExercisedMuscleGroup < ActiveRecord::Base
belongs_to :exercise
belongs_to :muscle_group
end
Here's what I have so far for the controller actions for new and create:
def new
#exercise = Exercise.new
#exercise.exercised_muscle_groups.build
end
def create
#exercise = Exercise.new(exercise_params)
#exercise.save
#then loop through all muscle groups marked as primary and then create a record for each one with value of "primary" for used_as column
#then loop through all muscle groups marked as secondary and then create a record for each one with value of "secondary" for used_as column
#if all saves are successful, then redirect to show page for that exercise
#if any save unsuccessful, then redirect to new page with error message
end
Here's what I have for the form in the view. I know it's wrong and it doesn't work.
<%=form_for(#exercise) do |exercise_form| %>
<%= exercise_form.label :name %>
<%= exercise_form.text_field :name, class: 'text_field' %><br>
<div class="col-xs-12">
<% exercise_form.fields_for :exercised_muscle_groups do |muscle_group_form| %>
<%= muscle_group_form.label :primary %>
</div>
<% MuscleGroup.all.each do |muscle_group| %>
<div class="col-xs-6">
<span class="col-xs-3">
<%= check_box_tag "exercise[muscle_group_ids][]", muscle_group.id %>
</span>
<span class="col-xs-3">
<%= muscle_group.name %>
</span>
</div>
<% end %>
<div class="col-xs-12">
<%= muscle_group_form.label :secondary %>
</div>
<% MuscleGroup.all.each do |muscle_group| %>
<div class="col-xs-6">
<span class="col-xs-3">
<%= check_box_tag "exercise[muscle_group_ids][]", muscle_group.id %>
</span>
<span class="col-xs-3">
<%= muscle_group.name %>
</span>
</div>
<% end %>
<% end %>
<%= exercise_form.submit "Submit", class: "btn btn-lg btn-primary" %>
<% end %>
How do I set up the form for the exercise and controller actions? Am I overcomplicating this? Is there an easier way?
Any help would be greatly appreciated. Thanks!

How to add text field in views to add content to other table inside a form

Im new to ror so sorry if that's a really basic question.
So, in my app i have quizzes and each quiz, beside questions and answers, should have 5 links.
class Quiz < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :questions
has_many :links
end
class Link < ActiveRecord::Base
belongs_to :quizzes
end
Schema looks like this:
create_table "links", force: true do |t|
t.string "name"
t.string "www"
t.integer "quiz_id"
end
create_table "questions", force: true do |t|
t.string "content"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "quiz_id"
end
create_table "quizzes", force: true do |t|
t.string "content"
t.datetime "created_at"
t.datetime "updated_at"
end
Now, in views I want to add links as i Add/Edit my quiz.
View for form looks like this:
<%= form_for(#quiz) do |f| %>
<% if #quiz.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#quiz.errors.count, "error") %> prohibited this quiz from being saved:</h2>
<ul>
<% #quiz.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
<%= **THIS IS PLACE FOR TEXT FIELD FOR LINK_NAME AND LINK_WWW** %>
</div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How do I create a form to add the links?
You can use fields_for:
<%= f.label :content %><br>
<%= f.text_field :content %>
<%= f.fields_for #quiz.links.new do |ff| %>
<%= ff.label :name %>
<%= ff.text_field :name %>
<% end %>
And allow the Quiz to update the Link records associated:
class Quiz < ActiveRecord::Base
accepts_nested_attributes_for :links

Can't get 'has_and_belongs_to_many' to work

Made a previous post about this but after a lot of testing and changing it's outdated.
I'm trying to tie users and activities together.(One user can have several activities. An activity can have several users). I'ts pretty much a multi-user agenda thing.
Whenever i create a new activity i can select users by checkbox which will be doing the activity.
I can't get it to work though; The users won't show up in my activity show. Printing #activity.users in my show results in #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_User:0x43d2158> but looping it, or checking my activities.js shows nothing(The activities.js shows "users":[] in the activity. So I'm pretty certain they're not associated properly.
Here's some code:
The activities.js index method
def index
#activities = Activity.all
respond_to do |format|
format.html
format.js {render_json #activities.to_json(:include => [:pictogram ,:users]) }
end
end
The activities' form(Loops all users)
<%= form_for(#activity) do |f| %>
<% if #activity.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#activity.errors.count, "error") %> prohibited this activity from being saved:</h2>
<ul>
<% #activity.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :start_date %><br>
<%= f.date_select :start_date %>
</div>
<div class="field">
<%= f.label :end_date %><br>
<%= f.date_select :end_date %>
</div>
<div class="users">
<% for user in User.all %>
<label class="activity">
<%= check_box_tag "activity[user_ids][]", user.id %>
<%= user.name %>
</label>
<% end %>
</div>
<div class="pictograms">
<% for p in Pictogram.all %>
<% #f.fields_for :pictograms do |x| %>
<%= p %>
<% #end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The schema.rb
ActiveRecord::Schema.define(version: 20130911095113) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "activities", force: true do |t|
t.string "title"
t.date "start_date"
t.date "end_date"
t.integer "pictogram_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "activities", ["pictogram_id"], name: "index_activities_on_pictogram_id", using: :btree
create_table "activities_users", id: false, force: true do |t|
t.integer "activity_id"
t.integer "user_id"
end
add_index "activities_users", ["activity_id"], name: "index_activities_users_on_activity_id", using: :btree
add_index "activities_users", ["user_id"], name: "index_activities_users_on_user_id", using: :btree
create_table "pictograms", force: true do |t|
t.string "title"
t.string "url"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "name"
t.text "avatar"
t.date "birthdate"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Activity.rb
class Activity < ActiveRecord::Base
belongs_to :pictogram
has_and_belongs_to_many :users
accepts_nested_attributes_for :pictogram, allow_destroy: false
accepts_nested_attributes_for :users, allow_destroy: false
end
User.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :activities
validates_presence_of :name, :on => :create
validates_presence_of :birthdate, :on => :create
accepts_nested_attributes_for :activities, allow_destroy: false
end
And the activity params from my activities controller
def activity_params
params.require(:activity).permit(:title,
:start_date,
:end_date,
:users,
:pictogram)
end
Try sth like this:
class Activity < ActiveRecord::Base
belongs_to :pictogram
has_and_belongs_to_many :users
accepts_nested_attributes_for :pictogram, allow_destroy: false
def user_ids=(values)
self.users << User.find(values)
end
end
#controller
def activity_params
params.require(:activity).permit(:title,
:start_date,
:end_date,
{:user_ids =>[]},
:pictogram)
end
I suggest you try some minimalist debugging first,
User.create!(...) # create a valid user record
Activity.create!(...) # same as above
User.all.first.activities << Activity.all.first
User.all.first.activities.any?
See if this works, also keep an eye on your join_table and check that actual records are being persisted. Your schema looks good as well.
I think, none of them read about the strong_parameters with nested attributes :
You can easily define :users_attributes in permit parameters for nested_attributes.
activities controller :
def activity_params
params.require(:activity).permit(:title,
:start_date,
:end_date,
users_attributes: [:id])
end
This is the ideal way to do this. Thanks

Resources