Rails: Datetime params are empty? - ruby-on-rails

In my post view, I have a _form with a title and releaseDate parameter.
In my controller I get the value from params[:post][:title], but the params[:post][:releaseDate] is empty.
post _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 :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :releaseDate %><br />
<%= f.datetime_select :releaseDate %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
posts_controller
def create
#title = params[:post][:title]
#date = params[:post][:releaseDate]
#post = Post.new(title: #title, releaseDate: #date)
#post.user_id = current_user.id
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
(I am not using #post = Post.new(params[:post]) because I want to do something with the title and releaseDate in the controller.)
post.rb (model)
class Post < ActiveRecord::Base
attr_accessible :releaseDate, :title, :user_id
belongs_to :user
end
Any suggestions on how I can get the datetime value from the form and into my controller?

releaseDate is not rails convention, try to rename field to release_date. Maybe this will help.
To proof this concept you can use so called virtual attributes: add release_date getter and setter to model like this (note that logs can help you to narrow down the problem) :
class Post < ActiveRecord::Base
attr_accessible :releaseDate, :title, :user_id
belongs_to :user
def release_date
date = read_attribute('releaseDate')
logger.debug("READ DATE IS #{date} aND CLASS IS #{date.class}") # see this in rails server logs
end
def release_date=(date)
logger.debug("WRITE DATE IS #{date} aND CLASS IS #{date.class}") # see this in rails server logs
write_attribute('releaseDate', date)
end
end
And in view replace all releaseDate with release_date

Related

created micropost with t.text :content, results in unpermitted parameter "text"

I've created a basic devise login with microposts which have :user_id from :users, and t.text :content. If it matters I generated this with a scaffold content:text. Here is the micropost controller:
class MicropostsController < ApplicationController
def new
#micropost = Micropost.new
end
def create
#micropost = Micropost.create(params[:content])
respond_to do |format|
if #micropost.save!
format.html { redirect_to microposts_path, notice: 'Micropost was successfully created.' }
format.json { render :show, status: :created, location: #micropost }
else
format.html { render :new }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
private
def micropost_params
params.require(:micropost).permit( :content)
end
end
However everytime I try and create/save a 'micropost' is results in 'unpermitted parameter:text'? Any help is appreciated.
_form.html.erb
<%= form_with(model: micropost, local: true) do |form| %>
<% if micropost.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(micropost.errors.count, "error") %> prohibited this micropost from being saved:</h2>
<ul>
<% micropost.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_field :text %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
The field in your form is text but your fields name is content. Change the text field in your form to :content.
This was just laziness on my part, the micropost new.html.erb had no form.label or form.text_are, additionally #micropost = Micropost.create was typed wrong as #micropost.create. Sorry guys!

Better way of handling complex form_for

(this is a re-post - I deleted the first post because I think I posted really poorly).
I'm new to programming, and I'm trying to handle an ROR form that sends data to 4 different models/tables, and at this point I'm banging my head into the wall. In sum, the use case is that a teacher inputs the following into a form: an error, a corresponding correction, an abstraction of the error, an abstraction of the correction, some tags that describe the abstraction, and an explanation.
When I press submit, I'm not getting any errors on the screen, but when I look at the server, the only thing that gets submitted successfully is the original error and correction - I get an unpermitted parameter: ec_abstractions for the rest (ec_abstractions is the first level of nesting). I'm starting to think that I'm just going about the entire question wrongly.
The form looks like this (maybe should be split into multiple forms on the same view page?)
<%= form_for #ec_explanation do |ec_explanation_form| %>
<% if #ec_explanation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#ec_explanation.errors.count, "error") %> prohibited this error-correction pair from being saved:</h2>
<ul>
<% #ec_explanation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%#= Insert here: all (or a single) q_response(s) that have not yet been added %>
<div class="field">
<%= ec_explanation_form.label :early_explanation %>
<%= ec_explanation_form.text_area :early_explanation %>
</div>
<div class="field">
<%= ec_explanation_form.label :full_explanation %>
<%= ec_explanation_form.text_area :full_explanation %>
</div>
<!--(this is just a test field for the "number_field" data type - I'm not convinced that we should input the stage like this)-->
<div class="field">
<%#= ec_explanation_form.label :stage %>
<%#= ec_explanation_form.number_field :stage %>
</div>
<%= ec_explanation_form.fields_for :ec_abstractions do |ec_abstractions_form| %>
<% if #ec_abstraction.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#ec_abstraction.errors.count, "error") %> prohibited this error-correction pair from being saved:</h2>
<ul>
<% #ec_abstraction.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= ec_abstractions_form.label :error_abstraction %>
<%= ec_abstractions_form.text_field :error_abstraction %>
</div>
<div class="field">
<%= ec_abstractions_form.label :correction_abstraction %>
<%= ec_abstractions_form.text_field :correction_abstraction %>
</div>
<%= ec_abstractions_form.fields_for :ec_pairs do |ec_pairs_form| %>
<div class="field">
<%= ec_pairs_form.label :error_phrase %>
<%= ec_pairs_form.text_field :error_phrase %>
</div>
<div class="field">
<%= ec_pairs_form.label :correction_phrase %>
<%= ec_pairs_form.text_field :correction_phrase %>
</div>
<% end %>
<%= ec_abstractions_form.fields_for :tags do |tags_form| %>
<div class="field">
<%= tags_form.label :tag, "Tag" %>
<%= tags_form.text_field :tag %>
</div>
<div class="field">
<%= tags_form.label :tag, "Tag" %>
<%= tags_form.text_field :tag %>
</div>
<div class="field">
<%= tags_form.label :tag, "Tag" %>
<%= tags_form.text_field :tag %>
</div>
<% end %>
<% end %>
(Include javascript (or bootstrap) that will generate extra tag fields onclick of a 'plus' button)
<div class="actions">
<%= ec_explanation_form.submit 'Submit Correction' %>
</div>
<% end %>
I have the following models:
class EcExplanation < ApplicationRecord
has_many :abstractions_explanations_joins
has_many :ec_abstractions, :through => :abstractions_explanations_joins
accepts_nested_attributes_for :abstractions_explanations_joins
end
class AbstractionsExplanationsJoin < ApplicationRecord
belongs_to :ec_explanation
belongs_to :ec_abstraction
accepts_nested_attributes_for :ec_abstraction
end
class EcAbstraction < ApplicationRecord
has_many :ec_pairs
has_many :tags_ec_abstractions_joins
has_many :tags, :through => :tags_ec_abstractions_joins
has_many :abstractions_explanations_joins
has_many :ec_explanations, :through => :abstractions_explanations_joins
accepts_nested_attributes_for :tags_ec_abstractions_joins
accepts_nested_attributes_for :ec_pairs
end
class EcPair < ApplicationRecord
belongs_to :response
belongs_to :ec_abstraction
end
class TagsEcAbstractionsJoin < ApplicationRecord
belongs_to :ec_abstraction
belongs_to :tag
accepts_nested_attributes_for :tag, :reject_if => lambda { |a| a[:tag].blank? }
end
class Tag < ApplicationRecord
has_many :tags_ec_abstractions_joins
has_many :ec_abstractions, :through => :tags_ec_abstractions_joins
end
And the following controller code:
class CorrectionStoragesController < ApplicationController
def index
#ec_explanations = EcExplanation.all
end
def show
end
def new
#ec_explanation = EcExplanation.new
#ec_abstraction = #ec_explanation.ec_abstractions.build
#ec_pair = #ec_abstraction.ec_pairs.build
3.times do
#tag = #ec_abstraction.tags.build
end
end
def edit
end
def create
#ec_explanation = EcExplanation.create(ec_explanation_params)
respond_to do |format|
if #ec_explanation.save
format.html { redirect_to new_correction_storage_path, notice: 'Correction storage was successfully created.' }
format.json { render :show, status: :created, location: #ec_explanation }
else
format.html { render :new }
format.json { render json: #ec_explanation.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #ec_explanation.update(ec_explanation_params)
format.html { redirect_to new_correction_storage_path, notice: 'Correction was successfully updated.' }
format.json { render :show, status: :ok, location: new_correction_storage_path }
else
format.html { render :edit }
format.json { render json: #ec_explanation.errors, status: :unprocessable_entity }
end
end
end
def destroy
#ec_explanation.destroy
respond_to do |format|
format.html { redirect_to correction_storages_url, notice: 'Correction was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def ec_explanation_params
params.require(:ec_explanation).permit(:early_explanation, :full_explanation, ec_abstractions_attributes: [:id, :error_abstraction, :correction_abstraction, ec_pairs_attributes: [:id, :error_phrase, :correction_phrase], tags_attributes: [:id, :tag]])
end
end
Any help would be greatly appreciated. Thanks
You will want to compare the parameters in log/development.log against what is permitted by CorrectionStoragesController#ec_explanation_params.
The error
unpermitted parameter: ec_abstractions
means that Strong Parameters rejected the parameter ec_abstractions because that is not in your whitelist. To have the form submit a parameter called ec_abstractions_attributes you need to set up accepts_nested_attributes_for in your EcExplanation model.
When your form has nested attributes like:
<%= form_for #ec_explanation do |ec_explanation_form| %>
...
<%= ec_explanation_form.fields_for :ec_abstractions do |ec_abstractions_form| %>
...
Then you need:
class EcExplanation < ApplicationRecord
accepts_nested_attributes_for :ec_abstractions

Rails 5: Object's parent ID being lost between the new action and the create action

I'm trying to create a post that will contain it's forum_id that the form resides in. I need both ID to save in the object to achieve that.
I initialize a new #post in the new action using #post = Forum.find(params[:forum_id]).posts.build
Which will spit out unsaved instance of a post containing it the forum_id just as intended.
I then fill out my form here:
<%= form_for #post, :url => {:controller => "posts", :action => "create"} 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 |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title, class: "form-control" %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_area :description, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-primary" %>
</div>
<% end %>
And when I click the submit button and inspect post_params with byebug after the line #post = Post.new(post_params) in the create action, only the :title and :description come through. The forum_id is lost in between actions and I cannot the save #post without it. I have :forum_id whitelisted in my post_params but it's not coming through. I would think that if an instance of post is created in the new action with a forum_id that it should persist into the create action inside post_params but something is wrong here. Here is the relevant information that might help with my issue.
My model's relationships:
# User model
has_many :forums
has_many :posts
# Forum model
belongs_to :user
has_many :posts
# Post model
belongs_to :user
belongs_to :forum
# post_controller
def new
#post = Forum.find(params[:forum_id]).posts.build
end
Post Controller
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
...
# Rest of actions
...
def post_params
params.require(:post).permit(:title, :description, :forum_id, :user_id)
end
end
Form doesn't submit forum_id because it doesn't exist on there
I think you need to add this to that form
<%= f.hidden_field :forum_id %>

data is not saved in joins table

I am working on a website, where a user can have multiple projects and multpile users can contribute to a single project.
I have a project model
class Project < ActiveRecord::Base
#associations
has_and_belongs_to_many :users
end
and a users model
class User < ActiveRecord::Base
#associations
has_and_belongs_to_many :projects
end
and I have created a joins table by the name - :projects_users
everything works fine when I run the code on rails console.
but when I try to do the save thing in the controller, the data is not being saved in the joins table.
Code for the controller
please help
class ProjectsController < ApplicationController
def new
#project = Project.new
end
def create
#user = User.find(session[:user_id])
#project = Project.new(project_params)
if #project.save
#project.users << #user
redirect_to #project
else
flash[:error] = "Project has not been created due to some error"
render 'new'
end
end
private
def project_params
params.require(:project).permit(:name,:description)
end
end
Try using nestes_attributes_for
class Answer < ActiveRecord::Base
belongs_to :question
end
class Question < ActiveRecord::Base
has_many :answers
accepts_nested_attributes_for :answers, allow_destroy: true
end
Controlller
def new
#question = Question.new
#question.answers.build
end
def create
#question = Question.new(question_params)
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'question was successfully created.' }
format.json { render action: 'show', status: :created, location: #question }
else
format.html { render action: 'new' }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
def question_params
params.require(:question).permit(:name, :description, answers_attributes:[:content, :id, :question_id])
end
You form should look like this
<%= form_for(#question) do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<%= f.fields_for :answer do |builder| %>
<%= builder.label :content %>
<%= builder.text_area :content %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
just changed
#project.users << #user
to
#user.projects << #project
and it started working.Dont know the reason yet but its working

Nested Form in Rails: questions answers

I have a problem with my rails application.
My models:
quiz: name
question: text, quiz_id
answer: text, question_id
right_answer: question_id, answer_id
A quiz has many questions. A single questions has many answers and a answer has only one right answer.
How can I solve this problem?
This is my form:
<%= form_for([#quiz, #question]) do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :text %><br>
<%= f.text_field :text %>
</div>
<%= f.fields_for :answers do |u| %>
<%= u.text_field :text, class: "form-control", id: "answer"%>
<% end %>
<div class="actions">
<%= f.submit %>
I want to add a radio box to each answer to select which answer is the right.
Questions-Controller:
def new
#question = Question.new
#question.answers.build
end
def create
#question = Question.new(question_params)
#question.quiz_id = #quiz.id
i = 0
until question_params[:answers_attributes].count
#answer = #question.answers.new(question_params[:answers_attributes]["#{i}"])
#answer.save
i += 1
end
respond_to do |format|
if #question.save
format.html { redirect_to quiz_questions_path(#quiz), notice: 'Question was successfully created.' }
format.json { render :show, status: :created, location: #question }
else
format.html { render :new }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
How can I do this in my Controller and in my form, because I only have one right_answer but I need 4 radio buttons in my form?
Thanks
= f.collection_radio_buttons :answer_id, #question.answers.all, :id, :name_with_initial
Add a new boolean field correct_answer in your answers table :
rails g migration add_correct_answer_to_answer correct_answer:boolean
questions_controller.rb
def new
#question = Question.new
4.times { #question.answers.build } # you can do it dynamically
end
def question_params
params.require(:question).permit(:text, answers_attributes: [:id, :text, :correct_answer])
end
questions/_form.rb
<%= f.fields_for :answers do |builder| %>
<%= render 'answer', f: builder %>
<% end %>
questions/_answer.html.erb
<%= f.label :text, "Answer" %>
<%= f.text_field :text %>
<%= f.radio_button :correct_answer %>
Then you can create a scope in question model to get correct answer of a particular question easily.

Resources