adding attributes to join_table from primary form - sql

Hi I have a primary model, recipes with a has_many association with ingredients, which also has_many recipes, my join table is recipes_ingredients, the join table has the columns recipe_id, ingredient_id, and quantity. The quantity is just a string for how many times that ingredient will be used in that recipe.
I have a form that creates the recipe and saves it in the database at the same time it creates and saves any ingredients that are given in the form with a nested attribute... I cannot for the life of me figure out how to add the quantity for this join-table using this same form. I would appreciate any help you can afford me... thank you so much in advance.
# models/recipe.rb
class Recipe < ApplicationRecord
belongs_to :user
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
validates :name, :content, :cook_time, presence: true
def ingredients_attributes=(ingredients_hash)
ingredients_hash.each do |i, ingredients_attributes|
if ingredients_attributes[:name].present?
ingredient = Ingredient.find_or_create_by(name: ingredients_attributes[:name].capitalize!)
if !self.ingredients.include?(ingredient)
self.recipe_ingredients.build(:ingredient => ingredient)
end
end
end
end
# models/ingredient.rb
class Ingredient < ApplicationRecord
has_many :recipe_ingredients
has_many :recipe, through: :recipe_ingredients
validates :name, presence: true
end
# models/recipe_ingredient.rb
class RecipeIngredient < ApplicationRecord
belongs_to :ingredient
belongs_to :recipe
end
# form
<%= form_with(model: instruction, local: true) do |form| %>
<% if instruction.errors.any? %>
<div id="error_explanation">
<h4><%= pluralize(instruction.errors.count, "error") %> prohibited
this instruction from being saved:</h4>
<ul>
<% instruction.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container">
<div class="row">
<div class="col-sm-6">
<h3 class="text-center">Recipe</h3>
<div class="fields">
<%= form.label :name %><br>
<%= form.text_field :name, :placeholder => "Name" %><br>
<%= form.label "Instructions" %><br>
<%= form.text_area :content, :placeholder => "Recipe
Instructions" %><br>
<%= form.label :cook_time %><br>
<%= form.text_field :cook_time, :placeholder => "(ex,. 45
mins)" %><br>
<%= form.hidden_field :user_id, value: params[:user_id] %>
</div>
</div>
<div class="col-sm-6">
<h3 class="text-center">Ingredients</h3>
<div class="row">
<div class="col-sm-6 checkbox">
<%= form.collection_check_boxes(:ingredient_ids,
Ingredient.all, :id, :name) %>
</div>
<div class="col-sm-6">
<%= form.fields_for :ingredients do
|ingredient_builder| %>
<%= ingredient_builder.text_field :name %><br>
<% end %>
</div>
</div>
</div>
</div>
<div class="row justify-content-center submit-row">
<div class="fields text-center">
<%= form.submit %>
</div>
</div>
</div>[![enter image description here][1]][1]

You should use accepts accepts_nested_attributes_for
Visit for more information:
Rails has_many :through nested form
https://www.pluralsight.com/guides/ruby-ruby-on-rails/ruby-on-rails-nested-attributes
http://guides.rubyonrails.org/form_helpers.html#building-complex-forms

Related

rails : create children for given parent_id

i need your help to create parent-child relation.
i have a problem to make the create of the child working fine.
this is the model:
class Nccheklist < ActiveRecord::Base
has_many :children, class_name: "Nccheklist", foreign_key: "parent_id"
belongs_to :parent, class_name: "Nccheklist"
def has_parent?
parent.present?
end
def has_children?
children.exists?
end
end
the controller:
def create
#nccheklist = Nccheklist.new(nccheklist_params)
if #nccheklist.save
redirect_to nccheklists_url, notice: 'Nccheklist was successfully created.'
else
render :new
end
end
and the view :
<%= form_for(#nccheklist) do |f| %>
<% if #nccheklist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#nccheklist.errors.count, "error") %> prohibited this nccheklist from being saved:</h2>
<ul>
<% #nccheklist.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div>
<%= f.collection_select(:parent_id, #rootcat, :id, :name) %>
</div>
<br/><br/>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
when i submit the form, parent_id always equal null on database !
can someone help me please.
thanks.
add the following to the class definition
accepts_nested_attributes_for :children, allow_destroy: true

Showing Nested Model Partials on user Index/profile page

I an struggling with the syntax of the controller for nested models. There are many other questions out there but i am not having any luck and i have reached my 2 day struggling threshold, so its time to ask!
I have 3 Models, User, Farm, Product. - User has_many Farms, Farm has_many Products.
On the user show page i display a list of farm/s created by the user in a partial...
#users_controller
def show
#user = User.find(params[:id])
#farms = #user.farms
end
#show.html.erb
<% if #user.farms.any? %>
<center><h4>My Farms(<%= #user.farms.count %>)</h4></center>
<hr>
<%= render #farms %>
This works as expected.
What i would like to do is display all the products of the farm, within the _farm partial, as a list. However I dont know what to add to the controller? Adding
#products = Product.find(params[:id])
obviously displays all products, not just one made by that farm. So how to i create the controller code and/or the partial code to only show the products created by that particular farm?
I was thinking along the lines of...
#products = Product.find(params[:farm_id])
but it does not work and seems to simple!
I obviously need to pass a key somewhere to the partial within the partial, but i have no idea how to do it!
Any Help will be massively appreciated...its driving me nuts!
Many thanks, Alex
EDIT ::
#product.rb
class Product < ActiveRecord::Base
attr_accessible :description, :farm_id, :name, :ammount, :price, :category, :pic, :longitude,
:latitude, :image
belongs_to :farm
mount_uploader :image, ImageUploader
#farm.rb
class Farm < ActiveRecord::Base
attr_accessible :content, :name, :user_id, :description, :street_name, :bldg_name, :region, :post_code,
:province, :contact_number, :swap, :organic, :deliver, :image, :products_attributes
belongs_to :user
has_many :products
acts_as_followable
validates :user_id, presence: true
accepts_nested_attributes_for :products
mount_uploader :image, ImageUploader
#user.rb
class User < ActiveRecord::Base
mount_uploader :avatar, ImageUploader
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :confirmable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :region,
:description, :avatar, :street_name, :bldg_name, :post_code, :province, :contact_number, :avatar,
:avatar_cache, :remove_avatar, :products_attributes, :product
# attr_accessible :title, :body
acts_as_follower
has_many :farms
has_many :swaps
has_many :products, :through => :farms
# validates_presence_of :image
# validates_integrity_of :image
# validates_processing_of :image
has_private_messages
EDIT 2 ::
#_products.html.erb
<hr>
<div class="row-fluid">
<div class="span3"> <%= image_tag product.image_url(:thumb) %> </div>
<div class="span5">
<h2><%= product.name %></h2>
<table>
<tr>
<td><strong>Ammount Available ::</strong></td>
<td><center><%= product.ammount %></center></td>
<td><strong>Kilos</strong></td>
</tr>
<tr>
<td><strong>Price/Kilo ::</strong></td>
<td><center><%= product.price %></center></td>
<td><strong>Euros</strong></td>
</tr></table>
</div>
<br><br><br>
<div class="span3">
<%= link_to "View Product", product, class: "btn btn-small btn-secondary" %>
<% if correct_user?(#user) %>
<%= link_to "delete", product, class: "btn btn-small btn-secondary", method: :delete, confirm: "You sure?" %><% end %>
</div>
-
#_farm.html.erb
<div class="<%= cycle("even", "odd") %>">
<div class="container">
<div class="row-fluid">
<div class="span2">
<%= image_tag farm.image_url %>
</div>
<div class="span2">
<%= farm.name %>
</div>
<div class="span4">
<span><%= " Location :: " %><%= farm.user.region %></span><br>
<span><%= " Can it be delivered :: " %><%= farm.deliver ? 'No' : 'Yes' %></span><br>
<span><%= " Is it Organic :: " %><%= farm.organic ? 'Yes' : 'No' %></span><br>
<span class="timestamp">Listed on <%= farm.created_at.strftime("%d %b. %Y") %> </span>
</div>
<div class="span4">
<br>
<br>
<br>
<%= link_to 'Sell A Product', new_farm_product_path(farm), class: "btn btn-small btn-secondary" %>
<%= link_to 'Edit Grow Spot', farm, class: "btn btn-small btn-secondary" %>
</div>
</div><!-- end container -->
</div>
<div class="row-fluid">
<div class="span2"></div>
<div class="span8">
<% for product in farm.products do %>
<%= render :partial => "product", :product => product %>
<% end %>
</div>
<div class="span2"></div>
Using <%= render #farms %> in a view means you must have a partial called _farm.html.erb in app/views/farms
in that partial you can use farm variable:
<% for product in farm.products do %>
<%= product.name %>
<%= product.price %>
....
<% end %>
no need to add something in controller.
update
<% for product in farm.products do %>
<%= render :partial => "product", :locals => { :product => product } %>
<% end %>
in app/views/farms/_product.html.erb
<div class="zzz">
<div><%= product.price %></div>
</div>

rails carrierwave gem error

I have succsfuly set up an image upload with the carrierwave gem.
but when I try to add an optional online url like so:
<%= form_for #rating, :html => {:multipart=>true} do |f| %>
<div class="field">
<%= f.file_field :pic_url %>
</div>
<div class="field">
<%= f.label :remote_pic_url_url, 'or image url' %>
<br/>
<%= f.text_field :remote_pic_url_url %>
</div>
<div class="actions">
<%= f.submit 'Upload Picture', :class => 'btn btn-primary' %>
</div>
<% end %>
then I get this error:
Can't mass-assign protected attributes:
my model is
class Rating < ActiveRecord::Base
attr_accessible :pic_url, :rating
mount_uploader :pic_url , ImageUploader
end
You need to be able to mass-assign the remote_pic_url_url attribute:
class Rating < ActiveRecord::Base
attr_accessible :pic_url, :remote_pic_url_url, :rating
mount_uploader :pic_url , ImageUploader
end

learning rails, trying to build blog categorization

I am working on building a blog with categorization. I am a bit stuck on how to implement categorization in the form. I have setup a has many through relationship and want to add check boxes to associate a blog with multiple categories. What I have so far is passing the categories through to the view, and I can list them out, however I cannot get the form_for method working for some reason.
Here is my code.
blog model
class Blog < ActiveRecord::Base
attr_accessible :body, :title, :image
has_many :categorizations
has_many :categories, through: :categorizations
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates :title, :body, :presence => true
end
Category Model
class Category < ActiveRecord::Base
has_many :categorizations
has_many :blogs, through: :categorizations
attr_accessible :name
end
Categorization Model
class Categorization < ActiveRecord::Base
attr_accessible :blog_id, :category_id
belongs_to :blog
belongs_to :category
end
Blog new controller
def new
#blog = Blog.new
#categories = Category.all
respond_to do |format|
format.html # new.html.erb
format.json { render json: #blog }
end
end
Blog new form view
<%= form_for(#blog, :url => blogs_path, :html => { :multipart => true }) do |f| %>
<% if #blog.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#blog.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% #blog.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 :body %><br />
<%= f.text_area :body %>
</div>
<div class="field">
Categories:
<% #categories.each do |category| %>
<% fields_for "blog[cat_attributes][]", category do |cat_form| %>
<p>
<%= cat_form.check_box :name %>
</p>
<% end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This code is my failing point
<% #categories.each do |category| %>
<% fields_for "blog[cat_attributes][]", category do |cat_form| %>
<p>
<%= cat_form.check_box :name %>
</p>
<% end %>
<% end %>
Although I am not positive I am approaching any of it right since I am currently learning. Any advice on how to accomplish this.
Thanks,
CG
First of all, you probably don't need a separate Categorization model unless there's a use case you haven't described here. You can set up a many-to-many relationship like this:
class Blog < ActiveRecord::Base
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
has_and_belongs_to_many :blogs
end
You should have a database table like this:
class CreateBlogsCategories < ActiveRecord::Migration
def change
create_table :blogs_categories, id: false do |t|
t.references :blog
t.references :category
end
end
end
Then you can construct the view like this:
<div class="field">
Categories:
<% #categories.each do |category| %>
<%= label_tag do %>
<%= check_box_tag 'blog[category_ids][]', category.id, #blog.category_ids.include?(category.id) %>
<%= category.name %>
<% end %>
<% end %>
</div>
Lastly, in your form_for, you specify url: blogs_path - you should remove this if you plan to use this form for the edit action as well, because that should generate a PUT request to /blogs/:id. Assuming you used resources :blogs in routes.rb, Rails will determine the correct path for you based on the action used to render the form.

Nested Form doesn't show assignments

I recently followed a tutorial about nested forms by Ryan Bates and did basically the same thing as he did just with other names. I wanted to nest assignments in the order form and I would like to build an assignment for every bun to that order and the user should put a count in the form.
So my controller looks like this
def new
#order = Order.new
#buns = Bun.all
#buns.each do |bun|
#order.assignments.build(:bun_id => bun.id)
end
end
And the _form partial looks like this
<%= form_for(#order) do |f| %>
<div class="field">
<%= f.label :user_id %><br />
<%= f.number_field :user_id %>
</div>
<div id="assignments" class="field">
<% f.fields_for :assignments do |builder| %>
<div id="assignment" class="field">
<%= builder.label :count, "Anzahl" %>
<%= builder.text_field :count %>
<%= builder.object.bun_id %>
<% end %>
</div>
</div>
<div class="field">
<%= f.label :due_to %><br />
<%= f.datetime_select :due_to %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The Order model has this part
has_many :assignments
has_one :user
accepts_nested_attributes_for :assignments
And the Assignments model this one:
attr_accessible :bun_id, :order_id, :count
belongs_to :bun
belongs_to :order
As i log the assignments out there are all, which should be build, so why weren't the fields rendered?
Thanks for your help!
You are missing an equal sign (=) in your erb :
<%= f.fields_for :assignments do |builder| %>