Rails 4 Permitted Params with nested attributes - ruby-on-rails

Alright, been looking everywhere for this one. Tried all the solutions. Maybe someone can help on this.
So, I have a WebRequest model that has many WebSites. Each WebSite belongs to a WebRequest. My problem is in the nested form. Ive gone in an permitted the params (atleast, based on the documentation I have) and everything works fine until I go into the server logs. Posted below
class WebRequest < ActiveRecord::Base
has_many :web_sites
accepts_nested_attributes_for :web_sites
end
and here is the WebSite model
class WebSite < ActiveRecord::Base
belongs_to :web_request, dependent: :destroy
end
_form.html.erb
<% 1.times do %>
<%= f.fields_for :web_site do |ff| %>
<%= ff.input :url %>
<%= ff.input :description %>
<% end %>
<% end %>
WebRequests Controller
class WebRequestsController < ApplicationController
def new
#web_request = WebRequest.new
# #web_request.web_sites.build
end
def index
#web_requests = WebRequest.all
end
def create
#web_request = WebRequest.new(web_request_params)
respond_to do |format|
if #web_request.save
RequestMailer.web_request_submit(#web_request).deliver
format.html { render partial: 'success' }
format.json { render action: 'show', status: :created, location: #web_request }
else
format.html { render action: 'new' }
format.json { render json: #web_request.errors, status: :unprocessable_entity }
end
end
end
def web_request_params
params.require(:web_request).permit(:web_needs, :primary_goal, :secondary_goal, : :call_to_action, :hero_image, :image_count, :existing, :resources, :web_examples, :special_functions, :social_network, web_sites_attributes: [:id, :url, :description])
end
end
And here is the server log:
Started POST "/web_requests" for 127.0.0.1 at 2014-07-10 15:56:12 -0400
Processing by WebRequestsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0iisNgGk/AhC4jRrp1cmKWVCBsCcSx5G2dueEI/+p2A=", "web_request"=>{"web_needs"=>"", "primary_goal"=>"", "secondary_goal"=>"", "call_to_action"=>"", "hero_image"=>"", "image_count"=>"", "existing"=>"", "web_site"=>{"url"=>"TROLL", "description"=>"TROLL"}, "resources"=>"", "special_functions"=>"", "social_network"=>""}, "commit"=>"Create Web request"}
Unpermitted parameters: web_site
Notice at how the form fields get passed but they get restricted out of making it to the DB.
THANKS!
Update::
Here is the full form path:
<%= simple_form_for(#web_request) do |f| %>
<% if #web_request.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#web_request.errors.count, "error") %>
prohibited this Web Request from being saved:</h2>
<ul>
<% #web_request.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container">
<div class="field">
<%= f.input :web_needs, label: 'What web needs do you have?' %>
</div>
<div class="container"><h5>Please list below 5 URL's and explanations of why you like them.</h5></div>
<% 1.times do %>
<%= f.fields_for :web_sites do |ff| %>
<div class="field">
<%= ff.input :url, label: "URL of example site" %>
</div>
<div class="field">
<%= ff.input :description, label: "Description of example site" %>
</div>
<% end %>
<% end %>
<div class="field">
<%= f.input :resources, label: 'Will you be providing any kind of resource on this page? e.g. chord chart download.' %></br>
</div>
</div>
<div class="actions">
<%= f.button :submit, :class => "button" %>
</div>
</div>
<% end %>
Update::Full error log
undefined method `url' for #<ActiveRecord::Associations::CollectionProxy []>
The line is here
<% 1.times do %>
<%= f.simple_fields_for :web_site, #web_request.web_sites do |ff| %>
<div class="field">
<%= ff.input :url, label: "URL of example site" %> <--ERROR HERE on ':url'
</div>
<div class="field">
<%= ff.input :description, label: "Description of example site" %>
</div>
<% end %>

Add to controller in new action:
def new
#web_request = WebRequest.new
#web_site = #web_request.web_sites.build
end
and form:
<%= f.simple_fields_for #web_site do |ff| %>
<%= ff.input :url %>
<%= ff.input :description %>
<% end %>
<% end %>
and web_request_params:
def web_request_params
params.require(:web_request).permit(:web_needs,
:primary_goal,
:secondary_goal,
:call_to_action,
:hero_image,
:image_count,
:existing,
:resources,
:web_examples,
:special_functions,
:social_network,
{ web_sites: [:id, :url, :description] })
end

In your controller in web_request_params change web_sites_attributes for web_site_attributes
In your controller remove the comment from #web_request.web_sites.build
In your view remove 1.times do
In yor form change f.fields_for :web_sites do |ff| with f.simple_fields_for :web_sites do |ff|

Related

rails: nested-form doesn't render in view

I have models like this
post.rb
has_many :items
accepts_nested_attributes_for :items
item.rb
has_one :heading, dependent: :destroy
has_one :content, dependent: :destroy
has_one :link, dependent: :destroy
has_one :movie, dependent: :destroy
has_one :photo, dependent: :destroy
has_one :quate, dependent: :destroy
accepts_nested_attributes_for :heading
accepts_nested_attributes_for :content
accepts_nested_attributes_for :link
accepts_nested_attributes_for :movie
accepts_nested_attributes_for :photo
accepts_nested_attributes_for :quate
heading,content,link,movie,photo,quate.rb
belongs_to :item
posts_controller.rb
def new
#post = current_user.posts.build
end
def create
#post = current_user.posts.build(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'created!!' }
else
format.html { render :new }
end
end
def post_params
params.require(:post).permit(:title, :description, :image,:user_id,
items_attributes:[:id, :order,
heading_attributes:[:id, :head],
photo_attributes:[:id, :image, :title, :q_url],
movie_attributes:[:id, :y_url],
quate_attributes:[:id, :quate, :q_url, :q_title, :q_comment],
content_attributes:[:id, :content],
link_attributes:[:id, :url, :l_text],
twitter_attributes:[:id, :t_url]
])
end
posts/new_and_edit.html.erb
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :description%>
<%= f.text_field :description %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.hidden_field :user_id %>
<%= f.submit %>
<%= render 'posts/item_form_fields', name: 'headings' %>
<%= render 'posts/item_form_fields', name: 'contents' %>
<%= render 'posts/item_form_fields', name: 'movies' %>
<%= render 'posts/item_form_fields', name: 'quates' %>
<%= render 'posts/item_form_fields', name: 'links' %>
<%= render 'posts/item_form_fields', name: 'photos' %>
posts/_item_form_fields.html.erb
<%= form_for(#post, remote: false) do |m| %>
<%= render 'items/form_fields', m: m, name: name %>
<%= m.submit "submit" %>
<% end %>
items/_form_fields.html.erb
<%= m.fields_for :items, #item do |b| %>
<%= b.hidden_field :order, value: '0' %>
<%= render "#{name}/form_fields", b: b %>
<% end %>
headings/_form_fields.html.erb
<%= b.fields_for :heading, #item.build_heading do |h| %>
<%= h.text_field :head %>
<% end %>
"I have a "_form_fields.html.erb" for content,link,movie, photo and quate as well. "
when I run rails server, the nested-models form doesn't show up on view.
Also I pressed "submit", console said that
param is missing or the value is empty: post
I don't get why its happen.
Do you have any idea?
Thanks
You need to correct some important things
In your posts#new action
def new
#post = current_user.posts.build
#item = #post.items.build
#item.build_heading
#item.build_content
#item.build_link
#item.build_movie
#item.build_photo
#item.build_quate
end
And your form code after all the changes should look like this
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :description%>
<%= f.text_field :description %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.hidden_field :user_id %>
<%= f.fields_for #item do |m| %>
<%= render 'items/form_fields', m: m %>
<%= render 'headings/form_fields', m: m %>
<%= render 'contents/form_fields', m: m %>
<%= render 'movies/form_fields', m: m %>
<%= render 'quates/form_fields', m: m %>
<%= render 'links/form_fields', m: m %>
<%= render 'potos/form_fields', m: m %>
<% end %>
<%= f.submit %>
<% end %>
And you need to change the contents of partials like below
#items/_form_fields.html.erb
<%= m.hidden_field :order, value: '0' %>
#headings/_form_fields.html.erb
<%= m.fields_for :heading do |h| %>
<%= h.text_field :head %>
<% end %>
And the same for the remaining partials as well.

Undefined method when saving an instance of my "Stop" model

My Rails App consists of touristic Routes. Each route has many stops and waypoints and stops have categories.
Waypoints are just the intermediate model between routes and stops because stops can belong to many routes.
So, when i try to save a Stop, i get the error:
undefined method `category' for #<Stop:0x007fa067acea90>
And the " if #stop.save" line is highlighted in red:
respond_to do |format|
if #stop.save
Waypoint.create(route_id: params[:route_id] , stop_id: #stop.id)
#print out category id or name here
category = params[:category]
In my stops controller i have this on create:
def create
#stop = Stop.new(stop_params)
respond_to do |format|
if #stop.save
Waypoint.create(route_id: params[:route_id] , stop_id: #stop.id)
#print out category id or name here
category = params[:category]
#once printed save it (stop category)
StopCategory.create(category_id: category, stop_id: #stop.id)
format.html { redirect_to #stop, notice: 'Stop was successfully created.' }
format.json { render :show, status: :created, location:#stop }
else
format.html { render :new }
format.json { render json: #stop.errors, status: :unprocessable_entity }
end
end
And on my waypoints controller i have this on create:
def create
#waypoint = Waypoint.create(waypoint_params)
redirect_to #waypoint.route
end
This is the stop model:
class Stop < ActiveRecord::Base
validates :description, length: { maximum: 140 }
validates :category, presence: true
#Image Uploader
mount_uploader :stop_image, StopImageUploader
#Relationship with stops and waypoints
has_many :waypoints
has_many :routes, through: :waypoints
# Relationship with categories
has_many :stop_categories
has_many :categories, through: :stop_categories
end
And this is the view where the form is :
<h2>Create a new stop:</h2><br>
<%= form_for(#stop) do |f| %>
<% if #stop.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#stop.errors.count, "error") %> prohibited this stop from being saved:</h2>
<ul>
<% #stop.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>
<select name="category" id=" " >
<option value="" disabled selected> Select a Category </option>
<% #categories.each do |category| %>
<option value="<%= category.id %>"> <%= category.name %> </option>
<% end %>
</select>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :stop_image %><br>
<%= f.file_field :stop_image %>
</div>
<div class="field">
<%= f.label :stop_lat %><br>
<%= f.number_field :stop_lat, :class => 'text_field', :step => 'any' %>
</div>
<div class="field">
<%= f.label :stop_long %><br>
<%= f.number_field :stop_long, :class => 'text_field', :step => 'any' %>
</div>
<%= hidden_field_tag :route_id, params[:id] %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<h2>Add existing stop</h2>
<br>
<%= form_for(#waypoint) do |f| %>
<div class="field">
<%= f.label :stop_id %><br>
<%= f.number_field :stop_id %>
</div>
<%= f.hidden_field :route_id %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit', edit_route_path(#route) %> |
<%= link_to 'Back', routes_path %>
<br>
<br>
<br>
</div>
Any ideas ?
Thanks!
Do you have a 'category' attribute in your Stop model? If not, then the following doesn't make sense:
validates :category, presence: true
That is where it's probably failing.
If you want to validate the presence of categories, you need to replace that check with something like this:
validate :has_categories
def has_categories # make this private
if categories.blank?
# add errors here
end
end
The following might also work:
validates :categories, presence: true
In the Stop model, you should replace the line
validates :category, presence: true
with
validates :categories, presence: true
because the validator takes the attribute/association name as argument, not the model name of the association.
Your association is called categories, so that's what you need to perform the validation on.

how do i get nested form value to input to database table, instead of nil?

I have a nested form in my rails app. The field that is nested is not adding values to the database.
I want an address added into my Places table. The address field is nested within a form that corresponds to the Post table.
I just pushed full code to github... http://goo.gl/wzjLK2
I think I am not doing something in my Posts Controller #CREATE
def create
#post = Post.new(post_params)
#place = Place.new params[:address]
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
For reference, my Posts form:
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<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 :status %><br>
<%= f.text_field :status %>
</div>
<div class="field">
<%= f.label :upload %><br>
<%= f.text_field :upload %>
</div>
<%= f.fields_for #post.place do |p| %>
<div class="field">
<%= p.label :address %><br>
<%= p.text_field :address %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My Posts model...
class Post < ActiveRecord::Base
belongs_to :place
belongs_to :user
has_many :comments
has_many :commenters, through: :comments, source: :user
accepts_nested_attributes_for :place
def place_for_form
collection = places.where(place_id: id)
collection.any? ? collection : places.build
end
end
Any help is so much appreciated. I've been stuck on this for two days now.
After running the code, I notice there is an error in the server console:
Unpermitted parameters: place
After change this #post.place in
<%= f.fields_for #post.place do |p| %>
<div class="field">
<%= p.label :address %><br>
<%= p.text_field :address %>
</div>
<% end %>
to :place, everything works fine.

Ruby on Rails - Edit not working

Trying to update a post that I've made in my Ruby on Rails project but nothing happens. It is really annoying since I don't get any errors and can't seem to figure out what I am doing wrong.
I think it worked before, but since I first wrote the different actions I've added multiple things to my "feed"-model, such as impressions and tags. Don't know if this has affected my update action...
My controller looks like this:
def edit
#feed = Feed.find(params[:id])
end
def update
#feed = Feed.find(params[:id])
respond_to do |format|
if #feed.update_attributes(params[:feed])
format.html { redirect_to #feed, notice: 'Feed was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #feed.errors, status: :unprocessable_entity }
end
end
end
My feed model looks like this:
attr_accessible :content, :tag_list, :guid, :language, :location, :published_at, :summary, :url, :title, :user_id, :thumbnail_url, :url_to_feed, :type_of_feed
has_many :impressions, :as=>:impressionable
validates_length_of :tag_list, :maximum => 10
acts_as_taggable
My view looks like this:
<h1>Editing feed</h1>
<%= render 'form' %>
<%= link_to 'Show', #feed %> |
<%= link_to 'Back', feeds_path %>
____________________ form
<%= form_for(#feed) do |f| %>
<% if #feed.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#feed.errors.count, "error") %> prohibited this feed from being saved:</h2>
<ul>
<% #feed.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 :content %><br />
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.label :location %><br />
<%= f.text_field :location %>
</div>
<div class="field">
<%= f.label :language %><br />
<%= f.text_field :language %>
</div>
<div class="field">
<%= f.label :tag_list, "Tags (seperated by spaces)" %><br />
<%= f.text_field :tag_list %>
</div>
<div class="actions">
<%= f.submit %>
</div>
The log entry
Started PUT "/feeds/1" for 127.0.0.1 at 2013-02-17 12:27:36 +0100 Processing by FeedsController#show as HTML
says,that the PUT request (sending your form data) is being processed by FeedsController#show, but it has to be processed by FeedsController#update. So your routes seem to be wrong. Check out the Rails Routing Guide.
I would use a feeds ressource, because it creates the correct routes automatically:
resources :feeds

Can't mass-assign protected attributes: quantities

I'm getting this error:
Can't mass-assign protected attributes: quantities
I looked up all the threads concerning this issue in the site, but couldn't find something to answer my problem. Here are the code snippets:
product.rb
class Product < ActiveRecord::Base
attr_accessible :name, :quantities_attributes
has_many :quantities
accepts_nested_attributes_for :quantities, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
new.html.erb
<% if #was_submitted %>
<%= form_for(:new_product_array, :url => products_path) do |f| %>
<% prefix ||= 0 %>
<% #new_product_array.each do |n| %>
<% n.quantities.build %>
<% prefix += 1 %>
<%= f.fields_for(prefix.to_s ) do |child| %>
<div class="field">
<%= child.label :name %><br />
<%= child.text_field :name%>
</div>
<%= render :partial => 'quantities/form',
:locals => {:form => child} %>
<% end %>
<% end %>
<div class="actions">
<%= submit_tag :submit %>
</div>
<% end %>
<% else %>
<%= form_tag new_product_path, :method => 'get' do %>
<p align=center>
How many Items are you Adding? (1-100)
<%= number_field_tag 'amount', 1, :in => 1...100 %>
</br>
To which storage?
<%= number_field_tag 'storage', 1, :in => 1...100 %>
<%= submit_tag "Next", :name => 'submitted' %>
</p>
<% end %>
<% end %>
<%= link_to 'Back', products_path %>
product_controller.rb
def new
#product = Product.new
if params['submitted']
#was_submitted = true
#amount_form = params['amount']
#new_product_array = []
(1..#amount_form.to_i).each do
#new_product_array << Product.new
end
#storage_form = params['storage']
else
#was_submitted = false
end
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #product }
end
end
def create
i=0
logger.info params[:new_product_array].inspect
params[:new_product_array].each do |new_product|
if new_product.last[:name] != nil
#new_product_array[i] = Product.new(new_product.last)
#new_product_array[i].save
i+=1
end
end
redirect_to(products_path)
end
quantity.rb
class Quantity < ActiveRecord::Base
belongs_to :product
attr_accessible :amount, :storage
end
quantity/_form.html.erb
<%= form.fields_for :quantities do |quant| %>
<div class="field">
<%= quant.label :storage %><br />
<%= quant.number_field :storage %>
</div>
<div class="field">
<%= quant.label :amount %><br />
<%= quant.number_field :amount %>
</div>
<% unless quant.object.nil? || quant.object.new_record? %>
<div class="field">
<%= quant.label :_destroy, 'Remove:' %>
<%= quant.check_box :_destroy %>
</div>
<% end %>
<% end %>
Overall what Im trying to do, is ask the user how much products to add, then make a form with the number of fields the user specifies and with one submit button add all of the products, whereas when you add a product you also add a quantity record which holds more information on the product.
You need a line like this:
attr_accessible :name, :quantities_attributes, :quantities
You have very bad code, it can be much simplier 100%.
Your problem is that form dont' know nothing about your resource (product), so it can't render 'smartly' fields "quantities_attributes", it renders "quantities" instead.

Resources