how to display data from a associated model - ruby-on-rails

Currently stuck on a problem
I have a company.rb model that has_many :applications
The application.rb model belongs_to :company and has_many :answers
The answer.rb model belongs_to :application.rb and has_many :users
The user.rb model has_many :answers
I allow a company to create an application. There they can input questions. The user can view them and their answers will be stored in answer.rb.
What I'm trying to do now is display all current_company.applications that have received an answer.
I tried this:
<% #applications.all.each do |f| %>
<%= f.answers.answer_1 %><br>
<% end %>
whilst having my controller:
def applicants
#applications = current_company.applications
end
however I get undefined method `answer_1'. It doesn't seem I'm available to access it. I store it like this:
the applications has a company_id and the answers has an application_id and a user_id.
I thought that by doing i the way I do now I'm able to access all applications created by the current company. From there I can view all application_id in the answers as those are the one's I'm outputting but it's not working.

I think you understood the way you can access nested models wrongly.
When an application has_many: :answers, then #application.answers is a collection you can iterate through. For example (in your view):
<% #applications.each do |application| %>
<% application.answers.each do |answer| %>
<%= answer.text %>
<% end %>
<% end %>
(assuming that your answer model has a text attribute).

Related

Using has_many :through with fields_for and checkboxes to create associations

That title's a mouthful.
So I have something like this:
class Company < ActiveRecord::Base
has_many :company_partner_associations
has_many :partners, through: :company_partner_associations
end
class CompanyPartnerAssociation
belongs_to :company
belongs_to :partner
end
class Partner
has_many :company_partner_associations
has_many :companies, through: :company_partner_associations
end
And on a company form, i'm trying to make a list of all Partners with a checkbox next to them. If I check one, it creates association. If I uncheck it destroys.
<%= f.fields_for :company_partner_associations, Partner.all do |p| %>
<%= f.check_box :partner_id %>
<% end %>
fails because the object getting passed is a Partner, so getting undefined partner_id on Partner
I'm sure there's a nifty solution out there! Thank you!
Do this:
<%= f.collection_check_boxes :partner_ids, Partner.all, :id, :name %>
No fields_for.
This will have to be accompanied in the controller with the following params:
params.require(:company).permit(:company, :params, partner_ids: [])
This should set the partner_ids in your #company model.
With HABTM, you can declare associative data by populating the "collection_singular_ids" method; HMT has the same method appended with the has_many relation:
Although this will replace the current associated objects, it is much simpler than calling f.fields_for - especially for picking partners.
--
You can also use collection_check_boxes which is meant for this purpose :)
Not totally sure this is the problem here, but I think it could be that your controller is just not permitting the array of partner ids. So in your company_partner_params in your company controller needs to permit something like partner_attributes: [:id]. The syntax might not be perfectly correct there, but if that's something you're missing, you should look around for that.
This is what I think the form should look like:
<%= form_for #company do |f| %>
<%= f.fields_for :partners, Partner.all do |partner| %>
...
<% end %>
<% end %>

How to construct a Rails for a many-to-many model?

I have a User, a Wiki, and a Collaborator model:
class User < ActiveRecord::Base
has_many :wikis
has_many :collaborators
end
class Wiki < ActiveRecord::Base
has_many :wikis
has_many :collaborators
end
class Collaborator < ActiveRecord::Base
belongs_to :user
belongs_to :wiki
end
When I am editing a Wiki's collaborators I would like the form to look something like this:
My problem is that I cannot figure out how to construct the form. I thought the following would work but <% form_for :collaborator do |f|%> doesn't result in anything being included in the resulting page.
<% form_for :collaborator do |f|%>
<% possible_collaborators.each do |user| %>
<%= check_box_tag 'wiki[collaborator_ids][]', user.id, wiki.collaborators.include?(user) %>
<%= user.name %>
<br />
<% end %>
<%= f.submit %>
<% end %>
As you didn't post your controller code I can't be entierly sure what you are trying to accomplish, but I think you are missing out on the accepts_nested_attributes_for (docs, tutorial with controller code).
Furthermore I can only recommend you the use simple_forms or formtastic as those gems do a good job when it comes to complex forms and help you a lot with the basic use cases.

Rails 4 - Making profile pages sharable

SOLUTION:
I changed this line of code and now it displays perfectly.
<% if answer.user == current_user %>
to
<% if answer.user == #user %>
I posted a similar question last night but this is a new one.
I am building a question/answer app. The questions are static and provided, not user generated. The data is being accessed via a nested relationship.
On the individual user page, I am showing the questions/answers for that specific user using the code below. It is working great. Unfortunately, I want users to be able to share their profile pages and with the way things are set up, users can only see their own stuff, not that of others. What do I need to change so that only the data for user 1 is displayed on /users/1 but user 2 can view it?
I am assuming it will have something to do with using params to find the user vs. current_user, but I'm not sure how to set it up.
Here is the code in my show.view.
<% #user.questions.uniq.each do |question| %>
<h3><div class="answer"><%= question.question %> </div></h3>
<% question.answers.each do |answer| %>
<% if answer.user == current_user %>
<div class="answer"><%= answer.answer %> <%= answer.created_at.strftime("(%Y)") %></div>
<% end %>
<% end %>
<% end %>
My models:
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class Question < ActiveRecord::Base
has_many :answers
has_many :users, through: :answers
end
class User < ActiveRecord::Base
has_many :answers
has_many :questions, through: :answers
end
My Routes:
resources :users do
resources :answers
end
I'm happy to provide any other code that would be helpful. Thanks!
Okay, then you need to have in your show method in user controller something like this:
#answers_to_one_question = Answer.all.where("question_id = ?", question_id)
or
#answers_to_one_question = User.all.answers.where("question_id = ?", question_id)
And in the show view something like this:
<%= render partial: "answer", collection: #answers_to_one_question, as: answer %>
I didn't test this code, but the logic is like this.

How to create related objects

So I have four models
class User
has_many :user_rows
end
class Assignment
has_many :rows
end
class Row
belongs_to :assignment
has_many :user_rows
end
class UserRow
belongs_to :user
belongs_to :row
end
On the assignment show view I want to loop through the rows and for each row have a user_row to capture user input.
My question is how to intialize the user rows. Would it be best to do this?
class AssignmentController
def show
#assignment = Assignment.include(:rows).find(params[:id])
end
end
Then in the view just use first_or_create
<%= #assignment.rows.each do |row| %>
<%= row.data %>
<%= form_for UserRow.where(row_id: row.id, user_id: current_user.id).first_or_create, remote: true do |f| %>
<%= form_fields %>
<% end %>
<% end %>
As you can see the objects need to be iterated over in the view.
Which I don't like particularly because it's initializing an object in the view. Or is it best to create all the user_rows for each row when a user signs up to the site and if a new row is created create a user_row for all users?
Or is there a better solution I've missed?
I guess, fields_for and accepts_nested_attributes_for might help you. You might check these documents.
fields_for (ActionView::Helpers::FormBuilder) - APIdock
accepts_nested_attributes_for (ActiveRecord::NestedAttributes::ClassMethods) - APIdock

Multiple checkboxes for a has_many through not saving

I am not sure why my checkboxes for a has_many through are not saving. This is a rather complex form (An online application for a language summer program) so in addition to regular applicant information, I am collecting attributes of a LanguageBackgroundAndInterest model using a fields_for. Part of these attributes are the books that the applicant used to learn the language. The code looks like this:
<%= f.fields_for :language_background_and_interest do |builder| %>
<div class="field">
<%= hidden_field_tag "language_background_and_interest[book_ids][]" %>
<% Book.all.each do |book| %>
<br><%= check_box_tag "language_background_and_interest[book_ids][]", book.id %>
<%= book.name.humanize %>
<% end %>
</div>
<% end %>
Both the language_background_and_interest and books are joined together using a has_many_through like so:
class LanguageBackgroundAndInterest < ActiveRecord::Base
attr_accessible :book_ids
has_many :language_background_books
has_many :books, through: :language_background_books
end
class Book < ActiveRecord::Base
attr_accessible :name, :publisher
has_many :language_background_books
has_many :language_background_and_interests, through: :language_background_books
end
# Join Table
class LanguageBackgroundBook < ActiveRecord::Base
attr_accessible :language_background_and_interest_id, :book_id
belongs_to :language_background_and_interest
belongs_to :book
end
I am not sure why the books from the checkboxes don't get assigned to the appropriate background model. Any ideas?
PS: Granted, this design is rather ambiguous (Why not make books belong to an applicant?), but I currently want to put up a prototype and I am also constrained by a dubious requirement. So I need this working.
I ended up reviewing my model design and simplified it. I also switched to Simple Form to ease up working with my complex forms.

Resources