What can prevent an attribute from being created in rails? - ruby-on-rails

Everything doesn't seem to be too hard but I've spent hours yet still can't get it working.
If I do Category.create(:name => "foo") in the rails console, a new category with its name gets created beautifully.
(0.2ms) begin transaction
SQL (0.3ms) INSERT INTO "categories" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", "2014-09-16 15:40:01.218700"], ["name", "foo"], ["updated_at", "2014-09-16 15:40:01.218700"]]
(14.5ms) commit transaction
=> #<Category id: 38, created_at: "2014-09-16 15:40:01", updated_at: "2014-09-16 15:40:01", name: "foo">
However, if I do it on the pages something goes wrong. My Category model has only one attribute which is "name", and I want all of them to be listed on my category index page.
<% #categories.each do |category| %>
<ul>
<li>
<b><%= category.name %></b><br />
<% category.products.each do |product| %>
<%= product.title %><br />
<% end %>
</li>
</ul>
<% end %>
<%= link_to "Create new category", categories_new_path %>
If I create a new category with its name in the console, it appears on the page with its name with no problem. But if I create it on the page, there's a category created with its name attribute being "nil". So please help me figure out where the problem is. I'm quite new to rails.
Here's my categories_controller.erb
class CategoriesController < ApplicationController
# load_and_authorize_resource
def new
#category = Category.new
end
def create
#category = Category.new(params[:name])
if #category.save
redirect_to categories_path
else
render 'new'
end
end
def index
#categories = Category.all
end
end
And here's my new.html.erb
<h1>New Category</h1>
<%= form_for(#category) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Back', categories_path %>
Here's what appears in the server after I hit the submit button.
Started POST "/categories?locale=en" for 127.0.0.1 at 2014-09-17 00:02:42 +0800
Processing by CategoriesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZdXcC/uEMA/jhGoGhYvp4lSHHfi/tmlm3CovJcYizJ0=", "category"=>{"name"=>"fwefewfw"}, "commit"=>"Create Category", "locale"=>"en"}
(0.1ms) begin transaction
SQL (0.2ms) INSERT INTO "categories" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2014-09-16 16:02:42.806041"], ["updated_at", "2014-09-16 16:02:42.806041"]]
(21.2ms) commit transaction
Note that there's no "name" being inserted in the sql statement.
I sense I missed something that is very basic. Well forgive me for being a newbie and thank you for the help!!

Looking at your tags, i think you are using rails 4 so you need to permit your attributes first. You can do it by this:
class CategoriesController < ApplicationController
# load_and_authorize_resource
def create
#category = Category.new(category_params)
if #category.save
redirect_to categories_path
else
render 'new'
end
end
private
def category_params
params.require(:category).permit(:name)
end
end
For details checkout Strong Parameters in Rails

It should be:
#category = Category.new(params[:category])
If you're on Rails 4, you should use the strong params and add the following method to your controller:
def category_params
params.require(:category).permit(:name)
end
And then change the Category.new line to:
#category = Category.new(category_params)
That's the new "safe" way to accept user-generated data in Rails models, and works really well once you get used to it.

Related

Rails Params returning a nil value. I can't pass in value via controller or form?

I have tried a few methods and checked all of the existing SO questions I can find and can't find an answer to the problem. I'm a Rails newbie.
I have these models:
Project (has_many WeeklyReflections, has_many ProjectTasks)
WeeklyReflection (belongs_to Project)
ProjectTask (belongs_to Project)
Standard devise user model
My Project show page displays a list of ProjectTasks for the week. Using simplecalendar.
I can navigate forward and back a week at a time, which then changes the URL from www.site.com/projects/3 to www.site.com/projects/3?start_date=2108-05-30, or www.site.com/projects/3?start_date=2108-05-13, and this then shows all the tasks related to that week.
What I want to do as well, is for each page create a weekly journal entry, only one of which can be created for the week, however, I'm having problems saving it to my controller - I've tried a few ways and also tried putting it in as a hidden field on a form, and still can't get it to work.
I've put start_date:<%= render inline: params[:start_date].inspect %> on both the Project show page and form it returns a value correctly, i.e. "start_date:"2018-04-28"" or it returns nil if on the default show page which is to be expected.
The two methods I've tried: are - accessing the start_date param via the controller (in the controller below) and also adding the following to the form:
<%= hidden_field_tag(:weekending, params[:start_date]) %> (I've also tried using .to_date, as I think the string it returns isn't in the right format)
However, both methods are returning a nil value when the start_date param is returning 2018-04-28 on the view page.
Console log after create action:
Started POST "/projects/6/weekly_reflections" for 2.96.199.78 at 2018-05-07 16:20:14 +0000
Cannot render console from 2.96.199.78! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by WeeklyReflectionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"UFCXjIp1SZrql2JckHk1HrzDlzO2/WLVwcdvdh+FQKbdrVMfdaivtjS32oLaFwcFs0UcupVP+XV6VVnNwrM0XQ==", "week_reflection"=>{"reflectionentry"=>"adasda", "motivationscore"=>"1", "beliefscore"=>"1"}, "weekending"=>"2018-04-28", "commit"=>"Create Project reflection", "project_id"=>"6"}
Project Load (0.6ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]]
(0.1ms) begin transaction
(0.1ms) commit transaction
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
(0.1ms) begin transaction
SQL (1.3ms) INSERT INTO "week_reflections" ("reflectionentry", "user_id", "project_id", "motivationscore", "beliefscore", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["reflectionentry", "adasda"], ["user_id", 2], ["project_id", 6], ["motivationscore", 1], ["beliefscore", 1], ["created_at", "2018-05-07 16:20:14.957131"], ["updated_at", "2018-05-07 16:20:14.957131"]]
(15.0ms) commit transaction
-
class WeeklyReflectionsController < ApplicationController
before_action :set_weekly_reflection, only: [:show, :edit, :update, :destroy]
before_action :set_project, only: [:new, :edit, :create, :show]
def index
#weekly_reflections= WeeklyReflection.all
end
def new
#weekly_reflection= WeeklyReflection.new
end
def create
#weekly_reflection= #project.weekly_reflections.create(project_reflection_params)
#weekly_reflection.user = current_user
#weekly_reflection.weekending = params[:start_date].to_date || Date.today.beginning_of_week
respond_to do |format|
if #weekly_reflections.save
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection was successfully created.' }
else
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection could not be added.' }
end
end
end
private
def weekly_reflection
#weekly_reflection= WeeklyReflection.find(params[:id])
end
def set_project
#project = Project.find(params[:project_id])
end
def weekly_reflection_params
params.require(:weekly_reflection).permit(:reflectionentry, :weekending, :motivationscore, :beliefscore)
end
end
Project show page:
<p id="notice"><%= notice %></p>
start_date:<%= render inline: params[:start_date].inspect %>
<div class="row well">
<div class="col-md-12">
<%= render 'project_detail' %>
</div>
<div class="col-md-12">
<% if #project.user == current_user && #project.active? %>
<br>
<%= render "project_tasks/task_modal" %>
<% end %>
</div>
<div class="col-md-12">
<%= render "project_reflection_calendar" %>
<% if #project.user == current_user && #project.active? %>
<h3>Add your thoughts for this week</h3>
<%= render "project_reflections/form_reflection" %>
<% end %>
</div
WeeklyEntry form, shown on the project show page:
<div class="row">
start_date:<%= render inline: params[:start_date].inspect %>
<%= form_for([#project, #project.weekly_reflections.build]) do |form| %>
<div class="col-md-12 projectform">
<%= form.label "Add your thoughts for this week" %>
<%= form.text_field :reflectionentry, :rows =>2, style: 'width:100%;' %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How motivated are you for your project this week?" %>
<%= form.select :motivationscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How strongly do you believe you will reach your project?" %>
<%= form.select :beliefscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<%= hidden_field_tag(:weekending, params[:start_date].to_date) %>
<div class="col-md-12 projectform">
<%= form.submit class:"btn btn-primary" %>
</div>
<% end %>
</div>
ApplicationRecord code:
class WeeklyReflection < ApplicationRecord
belongs_to :project
belongs_to :user
validates :reflectionentry, presence:true, length: {minimum:3, maximum: 540}
#required for simple_calendar
def start_time
self.weekending
end
end
class Project < ApplicationRecord
has_many :project_tasks, dependent: :destroy
belongs_to :user
has_many :weekly_reflections, dependent: :destroy
end
=> WeeklyReflection Schema:
(id: integer, reflectionentry: text, user_id: integer, project_id: integer, weekending: date, motivationscore: integer, beliefscore: integer, created_at: datetime, updated_at: datetime)
I think, this should work:
Add to your ProjectController show action:
#weekly_reflection= #project.weekly_reflections.new
Change in WeeklyReflectionsController:
def create
#weekly_reflection = #project.weekly_reflections.new(weekly_reflection_params)
#weekly_reflection.user = current_user
respond_to do |format|
if #weekly_reflections.save
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection was successfully created.' }
else
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection could not be added.' }
end
end
end
private
def weekly_reflection_params
params.require(:weekly_reflection).permit(:reflectionentry, :weekending, :motivationscore, :beliefscore)
end
Change in WeeklyReflection form:
<div class="row">
<%= form_for #weekly_reflection do |form| %>
<div class="col-md-12 projectform">
<%= form.label "Add your thoughts for this week" %>
<%= form.text_field :reflectionentry, :rows =>2, style: 'width:100%;' %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How motivated are you for your project this week?" %>
<%= form.select :motivationscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How strongly do you believe you will reach your project?" %>
<%= form.select :beliefscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<%= form.hidden_field :weekending, value: params[:start_date] || Date.today.beginning_of_week %>
<div class="col-md-12 projectform">
<%= form.submit class:"btn btn-primary" %>
</div>
<% end %>
</div>
Here we create #weekly_reflection variable inside the show action of ProjectsController, and just use it in form
That worked. Thanks so much.
With just a slight change to:
<%= form_for([#weekly_reflection.project, #weekly_reflection]) do |form| %>
I also had to add in:
<%= form.hidden_field :weekending, value: params[:start_date].try(:to_date).try(:beginning_of_week) || Date.today.beginning_of_week %>
So that I could capture the beginning of the week of the date in the param.

Unpermitted parameters: author

My requirements
Basically I'm adding books to a database, and I want to store the Author in a separate table. So I have a table called authors which is referenced by the table books.
I want to create a rails form for adding a book, and I'd like it to be just a simple form for Author, Title, Publisher etc, and if it finds the author already in the authors table then it should just reference that record, and if it isn't in the authors table then it should add a new record and reference it.
while storing values i am getting in log file
Unpermitted parameters: author
Processing by BooksController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8sxeOVMVJucl5nN+kMpSaT1cB1yDPnk5gfKElWPiT5k=", "book"=>{"book_name"=>"life ", "price"=>"20", "author"=>{"author_name"=>"swamy", "title"=>"LIFE", "publisher"=>"cta"}}, "commit"=>"Submit"}
swamy
LIFE
cta
Author Load (1.6ms) SELECT "authors".* FROM "authors" WHERE "authors"."author_name" = 'swamy' AND "authors"."title" = 'LIFE' AND "authors"."publisher" = 'cta' LIMIT 1
(0.6ms) BEGIN
SQL (25.2ms) INSERT INTO "authors" ("author_name", "created_at", "publisher", "title", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["author_name", "swamy"], ["created_at", "2015-07-01 03:53:22.712401"], ["publisher", "cta"], ["title", "LIFE"], ["updated_at", "2015-07-01 03:53:22.712401"]]
(16.8ms) COMMIT
Unpermitted parameters: author
(0.7ms) BEGIN
SQL (1.0ms) INSERT INTO "books" ("Author_id", "book_name", "created_at", "price", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["Author_id", 8], ["book_name", "life "], ["created_at", "2015-07-01 03:53:22.865106"], ["price", 20], ["updated_at", "2015-07-01 03:53:22.865106"]]
(22.4ms) COMMIT
my code
books_Controller
class BooksController < ApplicationController
def new
end
def create
#a=params[:author_name]
puts #a
b=params[:book][:author][:author_name]
puts b
# #c = #b.authors
# #d = #c.author_name
c=params[:book][:author][:title]
d=params[:book][:author][:publisher]
puts c
puts d
#author = Author.find_or_create_by(author_name: b,title: c, publisher: d)
#book = Book.new(books_params)
#book.Author = #author
#book.save
redirect_to root_url
end
private
def books_params
params.require(:book).permit(:book_name, :price,:author_attributes => [:author_name, :title, :publisher])
end
end
model
class Author < ActiveRecord::Base
end
class Book < ActiveRecord::Base
belongs_to :Author
accepts_nested_attributes_for :Author
# def author_name=(author_name)
# self.author = Author.find_or_create_by_name author_name
#end
end
view
books.html.erb
<%= form_for Book.new do |f| %>
<p>
<%= f.label :book_name %><br />
<%= f.text_field :book_name %>
</p>
<p>
<%= f.label :price %><br />
<%= f.text_field :price %>
</p>
<%= f.fields_for :author do |b| %>
<p>
<%= b.label :author_name%><br />
<%= b.text_field :author_name %>
</p>
<p>
<%= b.label :title%><br />
<%= b.text_field :title %>
</p>
<p>
<%= b.label :publisher%><br />
<%= b.text_field :publisher%>
</p>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
~
Hi sir i am new to rails i know it looks simple but i unable it find solution
~
~
That is because your books_params has author_attributes when it should be author based on your parameters.
This should work:
def books_params
params.require(:book).permit(:book_name, :price, :author => [:author_name, :title, :publisher])
end
Your code is full of errors. Follow my changes.
#book.rb
class Book < ActiveRecord::Base
belongs_to :author
accepts_nested_attributes_for :author
end
#books_controller.rb
def new
#book = Book.new
#book.build_author
end
def create
#book = Book.new(books_params)
if #book.save
redirect_to root_url
end
end
Finally in your form change <%= form_for Book.new do |f| %> to <%= form_for #book do |f| %>
Change authore to author_attributes in view file, like this.
<%= f.fields_for :author_attributes do |b| %>
<p>
<%= b.label :author_name%><br />
<%= b.text_field :author_name %>
</p>
Also change respectively in controller also. I think, this much is enough.
def create
#book = Book.new(books_params)
#book.save
redirect_to root_url
end
I will Suggested you just debug your code
def books_params
byebug
params.require(:book).permit(:book_name, :price, :author => [:author_name, :title, :publisher])
end
1: check your requested params
2: kindly check params.require(:book)
Requested parameter would be like
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8sxeOVMVJucl5nN+kMpSaT1cB1yDPnk5gfKElWPiT5k=", "book"=>{"book_name"=>"life ", "price"=>"20", "author_"=>{"author_name"=>"swamy", "title"=>"LIFE", "publisher"=>"cta"}}, "commit"=>"Submit"}
check with this link NestedAttributes
Your controller would be this
class BooksController < ApplicationController
def new
end
def create
#author = Author.create(params[:book])
redirect_to root_url
end
private
def books_params
params.require(:book).permit(:book_name, :price,:author_attributes => [:author_name, :title, :publisher])
end
end

Rails 4.1.8 "blog" posts not saving text or title when using strong parameters

I'm a long time lurker who's google-fu is failing him today. I've been learning to use Rails using a video series that was created before Rails 4 came out. As such, the lectures use the attr_accessibly mass assignments. I've been attempting to convert this to working strong parameters, but am having an issue actually saving info to my PostgreSQL database.
Basically, I should go to localhost:3000/new, add a title, body, and category, then submit. This goes off without a hitch, but my /posts (which lists all posts) shows the title as /posts/(whatever row number it's on), does not display the text, and only shows a date-time stamp when clicking on the post (url). Also, my database is only storing a post/row number.
Note: I am aware of things like ActiveAdmin, but would prefer to learn how to make/save posts manually before using such modules.
Here is the post controller:
class PostsController < ApplicationController
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
#category = Category.all
end
def create
#post = Post.create(post_params)
if #post.save
redirect_to posts_path, :notice => "Your post has been saved"
else
render "new"
end
end
def edit
end
def update
end
def destroy
end
private
def post_params
params.require(:post).permit(:title, :body, :category_id, :author_id)
end
end
Here is the html form:
<h1>Add New Post</h1>
<%= form_for #post do |f| %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %><br />
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %><br />
</p>
<p>
<%= f.select :category_id, Category.all.collect {|x| [x.name, x.id]}, {:include_blank=> "Select One"}%><br />
</p>
<p>
<%= f.submit "Add Post" %>
</p>
<% end %>
And finally, the posts.rb file:
class Post < ActiveRecord::Base
# Deprecated
# attr_accessible :title, :body, :category_id, :author_id
belongs_to :category
accepts_nested_attributes_for :category
end
I am no Ruby expert, so my first thought is that the .save method requires additional arguments when using strong_parameters. Adding (post_params) to the save method didn't seem to have an effect, and I haven't been able to determine my issue using the Ruby documentation. I'd prefer to do this the "right" way, as opposed to just using the protected_attributes gem to use a deprecated (seemingly less secure) method.
Thanks in advance for any assistance you may be able to offer. When I get rich, I'll buy you a Ferrari*.
*May or may not be a Hot Wheels replica.
Eidt 2: Here is what the server throws out when attempting to POST to my database. It mentions a mass assignment error, but I thought I wasn't using them (strong params instead). Pardon my newbiness:
Started POST "/posts" for 127.0.0.1 at 2015-03-11 18:28:13 -0700
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9Ybchogw5u+sYbZOFYZtbJbXBkWC5EuCIZNUmAKyAQI=", "post"=> {"title"=>"blahblahblah", "body"=>"blahblahblah", "category_id"=>"1"}, "commit"=>"Add Post"}
WARNING: Can't mass-assign protected attributes for Post: title, body, category_id
app/controllers/posts_controller.rb:18:in `create'
[1m[36m (0.0ms)[0m [1mBEGIN[0m
[1m[35mSQL (1.0ms)[0m INSERT INTO "posts" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2015-03-12 01:28:13.990971"], ["updated_at", "2015-03-12 01:28:13.990971"]]
[1m[36m (2.0ms)[0m [1mCOMMIT[0m
[1m[35m (0.0ms)[0m BEGIN
[1m[36m (0.0ms)[0m [1mCOMMIT[0m
Redirected to http://localhost:3000/posts
Completed 302 Found in 10ms (ActiveRecord: 3.0ms)
And the index view. This is a training exercise, so it's just text, no styling:
<h1>Blog Posts</h1>
<% #posts.each do |post| %>
<h3><%= link_to post.title, post %></h3>
<p><%= post.body %></p>
<% end %>
uncomment your request/permit line in post_params and actually add the param names into it
def post_params
params.require(:post).permit(:title, :body, :category_id, :author_id)
end
That is why you are getting no data in your posts - because you aren't getting any data out of params anymore.
If the permit/require line is causing a different bug for you - we will help you fix that, but commenting out the security measure is not the way to solve it.

has_many belongs_to relationship not passing through params

I am making a small store admin
Product.rb
class Product < ActiveRecord::Base
has_many :product_options
accepts_nested_attributes_for :product_options
end
ProductOption.rb
class ProductOption < ActiveRecord::Base
belongs_to :product
end
products_controller.rb
class Admin::ProductsController < AdminApplicationController
def index
#products = Product.all
end
def new
#product = Product.new
end
def create
#product = Product.new(product_params)
if #product.save
redirect_to admin_products_path
end
#product_option = #product.product_options.create(params[:product_option])
end
def edit
#product = Product.find(params[:id])
end
def update
#product = Product.find(params[:id])
if #product.update(product_params)
redirect_to admin_products_path
end
end
def destroy
#product = Product.find(params[:id])
#product.destroy
flash[:notice] = "#{#product.name} has been deleted."
redirect_to admin_products_path
end
def upload
uploaded_io = params[:id]
File.open(Rails.root.join('public', 'product_pics', uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end
end
private
def product_params
params.require(:product).permit(:name, :product_id, :position, :product_description, :product_image_type, :product_image, :product_detail, :product_option_id, :option_name, :product_option )
end
end
product_option_controller.rb
class Admin::ProductOptionsController < AdminApplicationController
def index
#product_options = ProductOption.all
end
def new
#product_option = ProductOption.new
end
def create
#product_option = ProductOption.new(product_option_params)
end
def show
#product_option = ProductOption.find(params[:id])
end
end
private
def product_option_params
params.require(:product_option).permit(:option_name, :ranking, :total_redeemed, :product_id)
end
end
_form.html.erb
<%= simple_form_for([:admin, #product] , :html => {:multipart => true}) do |f| %>
<section class="main_content-header">
<div class="main_content-header-wrapper">
<nav class="main_content-breadcrumbs">
<ul class="breadcrumbs">
<li><%= link_to "All Products", admin_products_path %></li>
<h1> Edit Product </h1>
</ul>
</nav>
<div class="main_content-header-save">
<%= link_to "Cancel", admin_products_path, id: "main_content-header-save-cancel" %>
<%= f.submit %>
</div>
</div>
</section>
<div class="main_content-section">
<section class="main_content-section">
<div class="main_content-section-area">
<%= f.input :name %>
<%= f.input :product_description %>
<%= f.input :product_detail %>
<%= f.file_field :product_image %>
<p> If this product has options, enter them below</p>
<%= f.simple_fields_for :product_option, #product_option do |option_form| %>
<%= option_form.input :option_name %>
<% end %>
</div>
</section>
</div>
<% end %>
server output: ... keeps saying that :product_option is not permitted
Started POST "/admin/products" for 127.0.0.1 at 2014-10-15 16:13:25 -0700
Processing by Admin::ProductsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"t96EMVlDND42HuVUzxWuss2bYDVhBokieTqN2Gz3N9I=", "commit"=>"Create Product", "product"=>{"name"=>"cvncvbn", "product_description"=>"cvbn", "product_detail"=>"", "product_option"=>{"option_name"=>"cvnbnvcb"}}}
Unpermitted parameters: product_option
SQL (1.5ms) BEGIN
SQL (0.4ms) INSERT INTO `products` (`created_at`, `name`, `product_description`, `product_detail`, `updated_at`) VALUES (?, ?, ?, ?, ?) [["created_at", "2014-10-15 23:13:25"], ["name", "cvncvbn"], ["product_description", "cvbn"], ["product_detail", ""], ["updated_at", "2014-10-15 23:13:25"]]
(0.4ms) COMMIT
Redirected to http://localhost:3000/admin/products
SQL (0.1ms) BEGIN
SQL (0.2ms) INSERT INTO `product_options` (`product_id`) VALUES (?) [["product_id", 119]]
(0.3ms) COMMIT
Completed 302 Found in 10ms (ActiveRecord: 2.8ms)
Started GET "/admin/products" for 127.0.0.1 at 2014-10-15 16:13:25 -0700
Processing by Admin::ProductsController#index as HTML
Product Load (0.3ms) SELECT `products`.* FROM `products`
Rendered admin/products/index.html.erb within layouts/admin (11.7ms)
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 7 ORDER BY `users`.`id` ASC LIMIT 1
Rendered admin/_header.html.erb (1.4ms)
Rendered admin/_nav.html.erb (0.4ms)
Completed 200 OK in 21ms (Views: 19.8ms | ActiveRecord: 0.6ms)
The record gets saved, so in the products options table there is just the product_id, .. but no other params....have tried a million things over the past 6 hours... so i dont really have a list of all the possible options, .. but if someone can see a glaring mistake your wisdom would be greatly appreciated.
--------------------------------------------------------------------------------------------
I figured it out, i was not using accepts_nested_attributes correctly these are the changes I had to get it all work.
-deleted the product_options controller (it was not needed)
-changed the product_params:
private
def product_params
params.require(:product).permit(:name, :product_id, :position, :product_description, :product_image_type, :product_image, :product_detail, :product_option_id,
:product_options_attributes => [:id, :option_name, :ranking, :total_redeemed, :product_id])
end
end
-deleted this line from the create action of the products controller
#product_option = #product.product_options.create(params[:product_option])
-added this line to the new action of the products controller
#product.product_options.build
-added an s to the ":product_option" in this loop (and deleted the '#product_option")
<%= f.simple_fields_for :product_option, #product_option do |option_form| %>
<%= option_form.input :option_name %>
<% end %>
the main change was adding the S... without it nested attributes was not being called at all
Try something like
def product_params
params.require(:product).permit(:name, :product_id, :position, :product_description, :product_image_type, :product_image, :product_detail, :product_option_id, :option_name, product_option: [:option_name] )
end

How do I permit date selector attributes in Rails and Formtastic

Latest
I have switched to Simple form. No problem with permitting date attributes there.
Recent attempts
I have put a demo repository on Github illustrating the problem:
This one uses formtastic and displays my problem with:
Unpermitted parameters: date_of_receipt(1i), date_of_receipt(2i), date_of_receipt(3i), date_of_receipt(i)
https://github.com/bigos/permit_date_selector/commit/9f142b79c51e71dca35c988125a2912b83b91972
This one doesn't use formtastic and works fine;
https://github.com/bigos/permit_date_selector/commit/4c53b934ac5cd3f04241bf462e7b677ef5d28335
Initial post
When I try to submit my form I get this message
Unpermitted parameters: date_of_receipt(i)
I have :date_of_receipt in the list of permitted parameters.
My form input selecting the date looks as follows:
<%= f.input :date_of_receipt, as: :date_select %>
Should I give up on formtastic and go back to standard forms?
I've created a fresh Rails app (using Rails 4.1.5 and Formtastic 2.3.1) to try to replicate, and I can't, so I'm closing. Here's what I had:
# Migration
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.string :body
t.datetime :published_at
t.timestamps
end
end
end
# Model
class Post < ActiveRecord::Base
end
# Controller
class PostsController < ApplicationController
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render :new
end
end
def show
#post = Post.find(params[:id])
end
protected
def post_params
params[:post].permit(:title, :body, :published_at)
end
end
# View
<%= semantic_form_for #post do |f| %>
<%= f.inputs do %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.input :published_at %>
<% end %>
<%= f.actions do %>
<%= f.action :submit %>
<% end %>
<% end %>
By simply permitting :published_at, I was able to successfully save a Post into the database with the time I had selected. Here's the development.log:
Started POST "/posts" for 127.0.0.1 at 2014-09-06 21:13:37 +1000
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Jv4Pd7aNgvjkCtzrX+gHNeCNfX3L8t6IpEOEAWzdeIo=", "post"=>{"title"=>"sdfgs", "body"=>"sdgfdfg", "published_at(1i)"=>"2019", "published_at(2i)"=>"1", "published_at(3i)"=>"1", "published_at(4i)"=>"00", "published_at(5i)"=>"01"}, "commit"=>"Create Post"}
(0.1ms) begin transaction
SQL (0.2ms) INSERT INTO "posts" ("body", "created_at", "published_at", "title", "updated_at") VALUES (?, ?, ?, ?, ?) [["body", "sdgfdfg"], ["created_at", "2014-09-06 11:13:37.685160"], ["published_at", "2019-01-01 00:01:00 .000000"], ["title", "sdfgs"], ["updated_at", "2014-09-06 11:13:37.685160"]]
(8.8ms) commit transaction
Redirected to http://localhost:3000/posts/3
Completed 302 Found in 12ms (ActiveRecord: 9.1ms)
There's no extra trickery required, this is how you do it :)
When you inspect the element on the page, you will see three different elements for date_select.
model[date_of_receipt(1i)], model[date_of_receipt(2i)], model[date_of_receipt(3i)]
So you will have to permit
date_of_receipt(1i), date_of_receipt(2i), date_of_receipt(3i)
in your controller

Resources