Has Many Through. How to get the access? - ruby-on-rails

Here is my models:
class Item < ActiveRecord::Base
has_many :price_group_lines
has_many :price_groups, through: :price_group_lines
attr_accessible :item_name, :item_id
validates :item_name, presence: true
def to_label
"#{item_name}"
end
end
class PriceGroup < ActiveRecord::Base
has_many :customers
has_many :price_group_lines
has_many :items, through: :price_group_lines
attr_accessible :price_group_name
validates :price_group_name, presence: true
def to_label
"#{price_group_name}"
end
end
class PriceGroupLine < ActiveRecord::Base
belongs_to :item
belongs_to :price_group
attr_accessible :item_id, :price_group_id, :price, :item, :price_group
validates :price, :item_id, :price_group_id, presence: true
end
View (show.html.erb) for Price Group controller
<h1> PRICE GROUP </h1>
<p> <%= #pg.price_group_name %> </p> <br>
<% #pg.items.each do |i|%>
<%= i.item_name %>
<% end %>
<br>
<%= link_to "PRICE GROUP List", price_groups_path %>
So, I have the access to item_name in show.html.erb, but i don't know how to get the access to "price" attribute in PriceGroupLine model. Something, like
i.items.price not working. Please, help!

Problem is because you have association of price, better said prices.
Your variable i is already item just call price_group_lines on it and you will get association on which you can call each and get each price.
<% #pg.items.each do |i|%>
<%= i.item_name %> # will display item name
<% i.price_group_lines.each do |pgl| %>
<%= pgl.price %> # will display price
<% end %>
<% end %>

Related

using has_many through with dynamic forms rails 4

I want to create an appointment form with dynamics forms. But I'm not getting what I'm doing wrong
I'm having trouble with the partial _appointment_record_form_fields and with appointment_controller.
Someone can help me fix the controller and the view?
My Models:
class Appointment < ActiveRecord::Base
has_many :appointment_record_forms, dependent: :destroy
has_many :record_forms, through: :appointment_record_forms
accepts_nested_attributes_for :appointment_record_forms, allow_destroy: true
end
class AppointmentRecordForm < ActiveRecord::Base
belongs_to :appointment
belongs_to :record_form
serialize :properties, Hash
def validate_properties
record_form.record_form_fields.each do |record_form_field|
if record_form_field.required? && properties[record_form_field.name].blank?
errors.add record_form_field.name, "must not be blank"
end
end
end
end
class RecordForm < ActiveRecord::Base
has_many :record_form_fields
has_many :appointment_record_forms, dependent: :destroy
has_many :appointments, through: :appointment_record_forms
accepts_nested_attributes_for :record_form_fields, allow_destroy: true
end
class RecordFormField < ActiveRecord::Base
belongs_to :record_form
end
My Controller
class AppointmentsController < ApplicationController
.
.
.
def appointment_params
params.require(:appointment).permit(:duration, :appointment_date, :patient_id, :doctor_id,
:record_forms => [:id, :name, :_destroy],
:record_form_fields => [:id, :name, :field_type, :require, :record_form_id, :_destroy])
end
end
Views:
views/appointment/_form
...
<%= f.fields_for :appointment_record_forms do |builder| %>
<%= render 'appointment_record_form_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Field", f, :appointment_record_forms %>
...
partial/_appointment_record_form_fields
<fieldset>
<%= f.fields_for :properties, OpenStruct.new(#appointment_record_forms.properties) do |builder| %>
<% #appointment_record_forms.record_form.record_form_fields.each do |record_form_field| %>
<%= render "appointments/fields/#{record_form_field.field_type}", record_form_field: record_form_field, f: builder %>
<% end %>
<% end %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
TKS

Rails 4 - Object reference output when displaying value from different model

I have three models, team, player, and ownerships. Their relationships look like this:
team.rb
class Team < ActiveRecord::Base
has_many :ownerships
has_many :players, through: :ownerships
validates :name, presence: true
validates :division, presence: true
end
player.rb:
class Player < ActiveRecord::Base
has_one :team, through: :ownership
has_one :ownership
validates :name, presence: true
validates :position, presence: true
end
ownership.rb
class Ownership < ActiveRecord::Base
belongs_to :player
belongs_to :team
validates :round, :pick, :team_id, presence: true
end
Ownerships is indexed off both player_id and team_id:
add_index "ownerships", ["player_id"], name: "index_ownerships_on_player_id"
add_index "ownerships", ["team_id"], name: "index_ownerships_on_team_id"
When I update an ownership, the player(s) show up fine when I show the team(show.html.erb). But when I display the players index view, I get weird output from <%= player.team %>. The team assignments are working, but, the team names get displayed as things like
#<Team:0x007f8f37a76f20> and #<Team:0x007f8f37a4c360>.
I've tried <%= player.team.name %>, but that throws an undefined method error.
How can I get the team names to display correctly? And what are those values I'm seeing above?
Thank you in advance.
This the pertinent part of the players index.html.erb page:
<% #players.each do |player| %>
<tr>
<td></td>
<td><%= player.name %></td>
<td><%= player.position %></td>
<td><%= player.team %></td>
</tr>
<% end %>
EDIT:
When I user <%= player.team.name %>, I get:
undefined method `name' for nil:NilClass
The index action from the players_controller.rb is basic:
def index
#players = Player.all
end
Would the way I'm selecting the players matter? I'm using a drop down menu in the ownership edit form that looks like this:
<%= form_for #ownership do |f| %>
<p>
<%= f.label :team_id %><br>
<%= #ownership.team.name %>
</p>
<p><%= f.label :player_id %><br>
<%= f.collection_select(:player_id, Player.all, :id, :name)%>
</p>
<p>
<%= f.submit %>
</p>
<% end %>

Nested form with values from model

I have a workout model:
class Workout < ActiveRecord::Base
attr_accessible :time
belongs_to :user
has_and_belongs_to_many :trainers
accepts_nested_attributes_for :trainers
end
And a trainer model:
class Trainer < ActiveRecord::Base
attr_accessible :name
validates_uniqueness_of :name
has_and_belongs_to_many :workouts
end
I need to have a nester trainer form, which allows to pull values from database.
Now I have this inside a new workout form:
<%= f.fields_for :trainers do |builder| %>
<%= builder.select :trainer, options_for_select(Trainer.all.collect{ |u| [u.name, u.id] }) %>
<br>
<% end %>
I get "undefined method `trainer' for #"
What am I doing wrong?
I forgot to add attr_accessible :trainers_attributes to Workout controller

using a validation with has_many_through

I want to set up a validation so that people can't submit a post unless they click on a category for that post and also to make sure that they can chose only one of the categorys for that post so the post can have only one category. Here are the modles
class Categorization < ActiveRecord::Base
belongs_to :post
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :categorizations
has_many :posts, :through => :categorizations
end
class Comment < ActiveRecord::Base
belongs_to :user
validates :content, presence: true,
length: { minimum: 5 }
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :categorizations
has_many :categories, :through => :categorizations
validates :title, :content, presence: true,
length: { minimum: 5, maximum: 140 }
end
also here is my form:
<%= form_for #post, :html => {:multipart => true} do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation" class="animated tada">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.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.file_field :image %>
</div>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<%= hidden_field_tag "post[category_ids][]", nil%>
<% Category.all.each do |category| %><br>
<%= check_box_tag "post[category_ids][]", category.id, #post.category_ids.include?(category.id), id: dom_id(category)%>
<%= label_tag dom_id(category), category.name %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</div>
do any of you know what I would need to put in to make my form come back with a message saying need to select category or can pick only one category?
We've done a similar thing with has_many :through
Validating On The Join Model
Our solution was to use accepts_nested_attributes_for, and validate on the join model. This could be seen as quite inefficient, but works well for us:
#app/models/message.rb
Class Message < ActiveRecord::Base
validates :title, :body,
:presence => { :message => "Needs A Value!" }
accepts_nested_attributes_for :message_subscribers, :allow_destroy => true
end
#app/models/message_subscriber.rb
Class MessageSubscriber < ActiveRecord::Base
#Validations
validates :subscriber_id,
:presence => { :message => "Your Message Needs Subscribers!" }
end
This returns an error if you don't have any subscriber_id's selected
Your Code
For you, I'd be tempted to do this:
class Categorization < ActiveRecord::Base
belongs_to :post
belongs_to :category
#Validation
validates :subscriber_id, :presence => { :message => "You need to select a category!" }
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :categorizations
has_many :categories, :through => :categorizations
#Validation
validates :title, :content, presence: true,
length: { minimum: 5, maximum: 140 }
end
I was going to include accepts_nested_attributes_for for you, but I realized it would be an inconvenient way to do something you're doing already. In light of this, I believe you may be best suited just performing the validations in your join model, however if it does not work, we'll add the accepts_nested_attributes_for functionality

Rails Nested Form - Can't mass-assign protected attributes:

I've used the nested_form gem, whenever i try and submit something to my form i get the Can't mass-assign protected attributes:items message, even though i've already put attr_accessible in my models.
Form:
<%= nested_form_for(#goods_in) do |f| %>
...
<%= f.fields_for :items do |i| %>
<td><%= i.text_field :description, :autocomplete => :off%></td>
<td><%= i.text_field :quantity, :autocomplete => :off %></td>
<th><%= i.link_to_remove "Remove this item" %></th>
<% end %>
<%= f.submit :"Submit Delivery" %>
<% end %>
Goods In Model:class GoodsIn < ActiveRecord::Base
belongs_to :supplier
has_many :items
attr_accessible :c4lpono,
:courier,
:deliverydate,
:deliverynoteno,
:destination,
:notes,
:quantity,
:signedby,
:supplier_id,
:partcode_ids
accepts_nested_attributes_for :supplier
validates :c4lpono,
:deliverydate,
:deliverynoteno,
:destination,
:quantity,
:signedby,
:presence =>true
end
Item Model
class Item < ActiveRecord::Base
belongs_to :goods_in
attr_accessible :quantity,
:partcode,
:description,
:goods_in_id
accepts_nested_attributes_for :goods_in
end
Goods In Controller:
def create
#goods_in = GoodsIn.new(params[:goods_in])
end
you have to add
attr_accessible :items_attributes
And here's a link to the documentation :)
I think there's an error in your Goods model.
It should read has_many :items instead of has_many :item.
It's hard to tell what you are trying to achieve with your models but I think you want the folllowing:
Your GoodsIn needs to have the relationship for accepts_nested_attributes_for :items . The belongs_to and accepts_nested_attributes_for is off.

Resources