Rails - Show associated data on Index view - ruby-on-rails

I'm struggling to have a belongs_to model iterate correctly inside a partial in an index page.
Classes:
class Chapter < ActiveRecord::Base
attr_accessible :name, :chapter_num,
belongs_to :chapter
#fields: :id, :name, :chapter_num
end
class County < ActiveRecord::Base
attr_accessible :name, :county_num, :chapter_id
has_many :counties
#fields: :id, :name, :county_num, :chapter_id
end
class ChaptersController < ApplicationController
def index
#chapters = Chapter.all
#counties = County.all(:joins => :chapter, :select => "counties.*, chapters.id")
end
end
app/views/chapters/index.html.erb:
<h1>Chapter Index</h1>
<%= render #chapters %>
<br />
<%= link_to "Add a new Chapter", new_chapter_path, class: "btn btn-large btn-primary" %>
app/views/chapters/_chapter.html.erb:
<div class="row">
<div class="span5 offset1"><h4><%= link_to chapter.name, edit_chapter_path(chapter.id) %></h4></div>
<div class="span2"><h4><%= chapter.chapter_num %></h4></div>
</div>
<!-- here's where the problem starts -->
<% #counties.each do |county| %>
<div class="row">
<div class="span4 offset1"><%= county.name %></div>
<div class="span4 offset1"><%= county.county_num %></div>
<div class="span2"><%= link_to 'edit', '#' %></div>
</div>
<% end %>
<%= link_to "New county", new_county_path %>
<hr>
The current code shows the screenshot below. The problem is it's iterating through all the counties, not just the counties associated with a given chapter.
How do I add a chapter specific variable within the partial that will cause the counties to iterate based upon the :chapter_id field since I'm in the index view, not the show view?

class ChaptersController < ApplicationController
def index
#chapters = Chapter.all
# #counties = County.all(:joins => :chapter, :select => "counties.*, chapters.id")
end
end
View:
<% chapter.counties.each do |county| %>

I think something like this would work for you:
<%= #chapters.each do |chapter| %>
<div class="row">
<div class="span5 offset1"><h4><%= link_to chapter.name, edit_chapter_path(chapter.id) %></h4></div>
<div class="span2"><h4><%= chapter.chapter_num %></h4></div>
</div
<% chapter.counties.each do |county| %>
<div class="row">
<div class="span4 offset1"><%= county.name %></div>
<div class="span4 offset1"><%= county.county_num %></div>
<div class="span2"><%= link_to 'edit', '#' %></div>
</div>
<% end %>
<%= link_to "New county", new_chapter_county_path(chapter) %>
<% end %>
Note that the key is to understand that because each chapter has many counties, you should iterate through the counties of each chapter via chapter.counties.each which will give you only the counties that belong to that particular chapter.
Also note the different link_to path for creating a new county. If you have your routes set up such that counties are nested under chapters, you should be able to do new_chapter_county_path(chapter)

Related

Params problems

I'm doing my first web api on Ruby on Rails (It's a Sale Point). The think here It's makes 'n' sales. So I used the nested_form for doing that, but when I 'confirm' the sale I'm having this problem:
ActionController::ParameterMissing in SalesController#create
param is missing or the value is empty: sale
private
def sale_params
params.require(:sale).permit(:fecha_venta, :id_usuario, carts_attributes: [:id ,:id_producto, :cantidad])
end
whith the strong params.This is controller for 'sale'
class SalesController < ApplicationController
def new
#venta = Sale.new
end
def create
#venta = Sale.new(sale_params)
#venta.id_usuario= current_user.id
#venta.fecha_venta = DateTime.now
if #venta.save
flash[:succes] = "Se ha realizado la venta"
redirect_to sales_index_path
else
flash[:danger] = "Ha ocurrido un error"
render new_sale_path
end
end
private
def sale_params
params.require(:sale).permit(:fecha_venta, :id_usuario, carts_attributes: [:id ,:id_producto, :cantidad])
end
end
I'm using nested_form in the model (and I've already installed the gem "nested_form"). Here is the sale and the cart model:
class Sale < ApplicationRecord
has_many :carts
accepts_nested_attributes_for :carts
end
class Cart < ApplicationRecord
belongs_to :sale
end
And finaly this is the partial form that I'm using
<%= nested_form_for(#venta) do |f| %>
<div class="form-group col-md-12">
<label class="form-control">Vendedor: <%= current_user.nombre_trabajador%></label>
</div>
<%= f.fields_for :carts do |carro| %>
<form class="form-horizontal">
<div class="card-body">
<div class="form-row">
<div class="form-group col-md-5">
<%= carro.collection_select :id_producto, Product.select("products.nombre_producto, products.stock, products.id").where("products.stock > ?", 0), :id, :nombre_producto, {:include_blank => true}, {:class => 'form-control btn btn-secondary dropdown-toggle'} %>
</div>
<div class="form-group col-md-5">
<%= carro.text_field :cantidad, class: "form-control", type: 'number' %>
</div>
<div class="form-group col-md-2">
<%= carro.link_to_remove "Eliminar", :class=> 'btn btn-danger btn-sm' %>
</div>
</div>
</div>
</form>
<% end %>
<div class="row">
<div class="form-actions">
<%= f.link_to_add "Agregar Producto", :carts , :class=> 'btn btn-default btn-sm'%>
</div>
</div>
<br>
<div class="form-actions">
<%= f.submit "Enviar" , :class=> 'btn btn-primary'%>
<%= link_to 'Cancelar', sales_index_path ,:class=> 'btn btn-danger' %>
</div>
<% end %>
I've benn traying to makea solution all day, but nothing.

How to solve undefined method in rails 5

First, sorry for my english,
I'm make a forum from scratch and I'm currently having an issue when I generate the post form
Showing D:/Lab/Rails/Forum/app/views/forumposts/_form.html.erb
undefined method `forumposts' for nil:NilClass
Model forumtopic.rb
belongs_to :forumforum
has_many :forumposts, :dependent => :destroy
belongs_to :user
Model forumpost.rb
belongs_to :forumtopic
belongs_to :user
forumposts_controller.rb
def create
#topic = Forumtopic.friendly.find(params[:forumtopic_id])
#forumpost = #topic.forumposts.create(params.require('forumpost').permit(:content))
if #forumpost.save
redirect_to forumtopic_path(#topic)
else
render 'new'
end
end
Views/forumposts/_form.html.erb
<% if signed_in? %>
<div class="wrapper">
<div class="post_form">
<%= simple_form_for([#topic, #topic.forumposts.build]) do |f| %>
<div>
<%= f.text_area :content, class: "post-textarea", placeholder: "Message", cols: 50, rows: 4 %>
</div>
<div>
<%= f.submit "Save ", class: "post-button" %>
</div>
<% end %>
</div>
</div>
<% end %>
views/forumtopics/show.html.erb
<div class="row">
<div class="col-md-12">
<div class="answer"> <%= #forum_topic.forumposts.count %> answers </div> **OK**
</div>
</div>
<%= render #forum_topic.forumposts %> **OK**
<% render 'forumposts/form' %> **Problem**
When I do that in console, I get all the topic's post:
#topic = Forumtopic.first
#topic.forumposts
Please help
thank you
In forumposts_controller.rb you should have action new with tne next code:
def new
#topic = Forumtopic.friendly.find(params[:forumtopic_id])
end

How to access an instance variables id in the view

I'm using carrierwave to upload photos into my app, the photos have a 'belongs_to' relationship with each location, and the location has a 'has_many' relationship to the photos. Im my show page where the photos for the locations are uploaded they display as normal through a loop. However, in my index page I'm looping through my locations and want to display a photo for that location. The photos have the correct location_id, I'm just not sure on the syntax in the view to access that locations photo. What I would like to do is display one of the photos that correlates to a specific location, something like: #photo(location.id.last). Any help would be much appreciated, thanks in advance.
View
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<%= image_tag #photos, :size => '400x300', :class => 'img-responsive' %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
controller
class PagesController < ApplicationController
def index
#locations = Location.all
#photos = Photo.all
end
def about
end
def faqs
end
def blog
end
def whats_included
end
end
Accessing photo with the help of association:
location.photos.last.photo.url
HTML
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<!-- changing #photos to location.photos.last -->
<% if location.photos.any? and location.photos.photo.present? %>
<%= image_tag location.photos.last.photo.url, :size => '400x300', :class => 'img-responsive' %>
<% end %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
Controller:
def index
#locations = Location.all
# no need to fetch photos now
# #photos = Photo.all
end
Photo Model
class Photo < ActiveRecord::Base
belongs_to :location
mount_uploader :photo, PhotoUploader
end
I see Sahil's post helped. Add .includes(:photos), to load Queries faster. In the future, will be super useful.
def index
#locations = Location.includes(:photos).all
end

Placing data from associated table in view

I have a class called Imprintable that contains this
class Imprintable < ActiveRecord::Base
has_one :brand
# ...
I also have a class called Style that contains the following:
class Style < ActiveRecord::Base
belongs_to :imprintable
# ...
My schema for Styles contains a foreign key to the imprintable table in the form of an integer called imprintable_id
I'm trying to display an attribute from the Style table called catalog_no in a view to edit information about an imprintable. I know what I have is wrong because style doesn't exist as a member of the imprintable table, but I'm not sure how to access the name of the catalog_no from the corresponding entry in the styles table. HTML is like this:
<!-- language: HTML -->
<div class="box-info">
<%= render partial: 'shared/modal_errors', locals: {object: imprintable} %>
<%= form_for(imprintable) do |f| %>
<div id="horizontal-form" class="collapse in">
<!-- Lots of HTML.. -->
<div class="form-group">
<%= f.label :style.catalog_no, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_field :style.catalog_no, class: 'form-control' %>
<!-- Problem is on the above line!! -->
<p class="help-block">The catalog number of the imprintable
</div>
</div>
</div>
<% end %>
</div>
Thanks for your time!
You should use nested form
Model Imprintable looks like this :
class Imprintable < ActiveRecord::Base
has_one :brand
accepts_nested_attributes_for :style
end
In controller edit action
def edit
#imprintable = Imprintable.find(params[:id])
end
In the view file edit.html.erb looks like
<div class="box-info">
<%= render partial: 'shared/modal_errors', locals: {object: imprintable} %>
<%= form_for(#imprintable) do |f| %>
<div id="horizontal-form" class="collapse in">
<%= f.fields_for :style do |d| %>
<div class="form-group">
<%= d.label :catalog_no, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= d.text_field :catalog_no, class: 'form-control' %>
<p class="help-block">The catalog number of the imprintable
</div>
</div>
<% end %>
</div>
<% end %>
</div>
If you're using rails 4, don't forget add style_attibutes to impritable_params method
private
def impritable_params
## params.require(:your_model).permit(:fields_of_model, association_model_attributes: [:fields_of_association_models])
params.require(:imprintable).permit(style_attributes: [:id, :catalog_no])
end
end

Rails: create two nested items in controller but only one shows in the view

Consider the following:
customer.rb
module Refinery
class Customer < Refinery::Core::BaseModel
has_many :users, :class_name => "Refinery::User"
accepts_nested_attributes_for :users
end
end
end
user_decorator.rb
Refinery::User.class_eval do
belongs_to :customer, :class_name => 'Refinery::Customer'
end
customer_controller.rb
module Refinery
class UsersController
def new
#customer = ::Refinery::Customer.new
# tried using build here as well with no sucess
#owner = #customer.users.new
#inputer = #customer.users.new
# raise #customer.users.length.to_yaml => returns 2 so that works!
end
end
end
new.html.erb
<%= form_for #customer do |f| %>
<% if #customer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#customer.errors.count, "error") %> need to be corrected before continuing:</h2>
<ul>
<% #customer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<!-- company fields here -->
<%= fields_for :users do |user| %>
<div>
<%= user.label :first_name %>
<%= user.text_field :first_name %>
</div>
<div>
<%= user.label :last_name %>
<%= user.text_field :last_name %>
</div>
<!-- more user fields here etc -->
<% end $>
<% end %>
When I view this page only one user shows up. The ids for the fields look like this also:
<div>
<label for="users_last_name">Last name</label>
<input id="users_last_name" name="users[last_name]" size="30" type="text">
</div>
I think there should be some kind of index in there right? (i.e. 0, 1, 2 etc for as if iterating over an array.
What am I doing wrong?
You missed the
f.fields_for
Just add it and it should work

Resources