Partner() expected, got String() - ruby

I have a course model and there is a many to many relationship with category, i am using a multi select on my form to get an array of objects, A course also can have a partner and the user can select this from a single select, but when i want to save to the database I call the params then I get a string instead of an object. not to sure how I can solve this
<%= form_for #course do |f| %>
<section class="new_course">
<div class="row collapse">
<div class="medium-5 small-centered column">
<%= f.label :course_title, :class=>"custom-prefix-class" %>
<%= f.text_field :title, :autofocus => true, :class=>"custom-input-class" %>
</div>
</div>
<div class="row collapse">
<div class="medium-5 small-centered column">
<%= f.label :start_date, :class=>"custom-prefix-class" %>
<%= f.text_field :start_date, :class=>"custom-input-class" %>
</div>
</div>
<div class="row">
<div class="medium-5 column with_chosen">
<%= f.collection_select :categories,
Category.all ,:id,:name,
{ include_blank: true},
{ class: 'chosen-select', :multiple=>true, :data => { :placeholder => ' ' }}
%>
</div>
</div>
<div class="row">
<div class="medium-5 column">
<%= f.collection_select :partner,
Partner.all.collect, :id,:name ,
{ include_blank: true },
{ class: 'chosen-select', :multiple=>false, :data => { :placeholder => ' Brand Partner' }}
%>
</div>
</div>
In my controller
def create
#course = Course.new(course_params)
end
if #course.save
render :action=>'new'
end
end
private
def course_params
params.require(:course).permit(:title, :start_date,:duration,:partner,:categories => [])
end
//rails server output
Started POST "/courses" for 127.0.0.1 at 2014-02-07 16:45:28 +0200
Processing by CoursesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"sKhAF2X6VOXTxZC9Pt51RFQfZSKdzXVWji6x4uwg+rI=", "course"=>{"title"=>"Marketing ", "start_date"=>"14-02-2014", "categories"=>["", "1", "2"], "partner"=>"1", "duration"=>"2-weeks"}, "commit"=>"Add new course"}
Completed 500 Internal Server Error in 3ms
ActiveRecord::AssociationTypeMismatch (Partner(#70274068591140) expected, got String(#70274066607160)):
app/controllers/courses_controller.rb:24:in `create'

try this out:-
it seems as that partner is a model and course has_one partner, so you
have to assign partner class object instead of id as string
actually as you can see in in question above value of
params[:course][:partner]
=> "1"
is a string now if you try to do something like #course.partner
= '1' it will raise an error like above, as on left hand side we have parter association and right and side a string.
just do this
def course_params
params.require(:course).permit(:title, :start_date,:duration,:partner,:categories => [])
if params[:course][:partner].present?
params[:course][:partner] = Partner.find params[:course][:partner]
end
end

Related

rails 5.1: nested form validation

I have a parent model called user and 2 nested models called award and certification. when I go to save a certification the model validation for award tells me that awards is blank, and when I got to save an award I get an error that says the validations for certification is blank. not sure what's going on.
here my user model
has_many :certifications, dependent: :destroy
has_many :awards, dependent: :destroy
# allows for nested attributes in the user views.
accepts_nested_attributes_for :work_histories, :qualifications, :certifications, :courses, :awards,
:languages, :patents, :publications, allow_destroy: true
here my award model
class Award < ApplicationRecord
belongs_to :user
validates :award_name, :award_granted_by, :award_date, :award_description, presence: true
end
and my certification model
class Certification < ApplicationRecord
belongs_to :user
validates :certification_name, :certification_authority, :certification_number, :certification_from,
:certification_to, presence: true
end
strong params in users_controller
def user_params
params.require(:user).permit( :first_name, :last_name, :email, :phone, :current_job_title, :password, :password_confirmation,
work_histories_attributes: [:user_id, :id, :_destroy, :job_title, :company, :description, :city, :state,:start_date, :end_date],
qualifications_attributes: [:user_id, :id, :_destroy, :education, :university, :university_major, :graduation_year, :currently_enrolled, :location],
awards_attributes: [:user_id, :id, :_destroy, :award_name, :award_granted_by, :award_date, :award_description],
certifications_attributes: [:user_id, :id, :_destroy, :certification_name, :certification_authority, :certification_number, :certification_from, :certification_to, :cert_never_expires],
courses_attributes: [:user_id, :id, :_destroy, :course_name, :course_number, :course_description],
languages_attributes: [:user_id, :id, :_destroy, :language, :language_proficiency],
patents_attributes: [:user_id, :id, :_destroy, :patent_title, :patent_office, :patent_number, :patent_status, :patent_date, :patent_description],
publications_attributes: [:user_id, :id, :_destroy, :publication_title, :publication_source, :publication_date, :publication_description] )
end
here's a part of the User form. I've got a button dropdown that has several options, when a user selects an option that particular div will be shown with a modal window.
<!-- one-to-many nested attributes -->
<%= form_for(#user) do |form| %>
<!-- a partial is rendered based on the user dropdown selection -->
<div id="award">
<%= render partial: "awards/new_award_modal", locals: { form: form } %>
</div>
<div id="cert">
<%= render partial: "certifications/new_certification_modal", locals: { form: form } %>
</div>
<%= form.submit 'Save', id: "submit-achievement", class: 'btn btn-primary form-control' %>
</div><!-- modal body -->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<% end %><!-- form_for -->
here is the partial for certifications
<div class="new_cert">
<%= form.fields_for :certifications, Certification.new do |cert_field| %>
<div class="field">
<%= cert_field.label :certification_name, 'Certification Title' %>
<%= cert_field.text_field :certification_name, class: "form-control" %>
</div>
<div class="field">
<%= cert_field.label :certification_authority %>
<%= cert_field.text_field :certification_authority, class: "form-control" %>
</div>
<div class="field">
<%= cert_field.label :certification_number %>
<%= cert_field.text_field :certification_number, class: "form-control" %>
</div>
<table>
<tr>
<td>
<div class="field">
<%= cert_field.label :certification_from, "From" %><br />
<%= cert_field.date_select :certification_from,{ :order => [:day, :month, :year],
:start_year => Date.current.year, :end_year => 1960,
:prompt => {day: 'Day', month: 'Month', year: 'Year'}, :discard_day => true }, class: 'form-control' %>
</div>
</td>
<td> </td>
<td>
<div class="field">
<%= cert_field.label :certification_to, "To" %><br />
<%= cert_field.date_select :certification_to, { :order => [:day, :month, :year],
:start_year => Date.current.year + (10), :end_year => 1960,
:prompt => {day: 'Day', month: 'Month', year: 'Year'}, :discard_day => true }, class: 'form-control' %>
</div>
</td>
</tr>
</table>
<div>
<%= cert_field.label :cert_never_expires, "This certification does not expire", class: "l" %>
<%= cert_field.check_box :cert_never_expires, class: 'cb' %>
</div>
<br />
<% end %>
</div><!-- ./new_cert -->
here's the awards partial
<div class="new_award">
<!-- nested attributes for award modal -->
<%= form.fields_for :awards, Award.new do |award_field| %>
<div class="field">
<%= award_field.label :award_name, 'Award or Honor Name' %>
<%= award_field.text_field :award_name, class: "form-control" %>
</div>
<div class="field">
<%= award_field.label :award_granted_by, "Granted by" %>
<%= award_field.text_field :award_granted_by, class: "form-control" %>
</div>
<div class="field form-inline">
<%= award_field.label :award_date, 'Date' %><br />
<%= award_field.date_select :award_date, { :order => [:day, :month, :year],
:start_year => Date.current.year, :end_year => 1960,
:prompt => {day: 'Day', month: 'Month', year: 'Year'},
:discard_day => true }, class: 'form-control ds' %>
</div>
<div class="field">
<%= award_field.label :award_description, 'Description' %>
<%= award_field.text_area :award_description, class: "form-control" %>
</div>
<% end %><!-- ./fields_for -->
</div>
so both awards and certifications can be saved to the database without any issue when there are no validations. however, when I just do a simple validation checking for presence of an attribute in the form that's when things get weird. The award model is saying that the certification form is empty, which it should be because I'm submitting the award form. And the opposite is also true, when I go to submit a certification the award validation is triggered saying the award form is blank.
It would be best to see the specific error you're getting, but I'd make sure that your form is setting the nested attributes appropriately, and that your user controller has nested attributes setup within the strong parameters.
There's documentation in the Rails guides: http://api.rubyonrails.org/classes/ActionController/StrongParameters.html

how to check the collection_radio_buttons selected for if condition? Rails

I have this form
<div class="form-group">
<%= f.label :status %>
<%= f.collection_radio_buttons(:status, options_for_status, :id, :description) do |b| %>
<div class="radio">
<%= b.label { b.radio_button + b.value} %>
</div>
<% end %>
</div>
if ??
#<% f.hidden_field :data_fim, :value => Date.today %>
When the user selects a specific radiobuton, he must execute hiden_field.
STATUS = {:Aguardando => 1, :'Em atendimento' => 2, :Finalizado => 3}
These are the options present for the user, I want to set set date_fim when the user select the radio
:Finalizado => 3
Would JS be my only option? Someone to help a noob in ruby?
This should work, assuming that jQuery is included in your assets.
<script type="text/javascript">
$(document).ready(function(){
$('.radio').click(function(){
$('#data_fim').val($(this).val());
});
});
</script>

Rails 4: Receiving the following error: First argument in form cannot contain nil or be empty

I am receiving the following error on a project of mine: First argument in form cannot contain nil or be empty. I am trying to create an edit page for my code. Fairly new with Rails and trying to learn without scaffolding.
Controller:
class BooksController < ApplicationController
def new
#book = Book.new
#authors = Author.all
end
def edit
#book = Book.find(params[:id])
end
def show
#Notice how the #books is plural here.
#books = Book.all
#authors = Author.all
##books = Book.where(id: params[:id])
end
#Create method will save new entries
def create
#book = Book.new(book_params)
#authors = Author.all
if #book.save
flash[:success] = "Book Added to Databse!"
redirect_to #book
else
render 'new'
end
end
private
#Note that this method will go up into the create method above.
def book_params
params.require(:book).permit(:title, :pub_date, :publisher, :author_id)
end
end
Model Page: (For Book)
class Book < ActiveRecord::Base
validates :title, :pub_date, :publisher, presence: true
validates :title, uniqueness: true
belongs_to :author
end
Model Page: (For Author)
class Author < ActiveRecord::Base
validates :name, presence: true
validates :name, uniqueness: true
has_many :books
end
Edit page:
<h1>Update a book entry</h2>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#book) do |f| %> **ERROR SEEMS TO BE RIGHT HERE!!!**
<%= render 'form' %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :pub_date %>
<%= f.text_field :pub_date, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :publisher %>
<%= f.text_field :publisher, class: 'form-control' %><br />
</div>
<div class="form-group">
<%= f.select(:author_id,
#authors.collect {|a| [ a.name, a.id ]},
{:include_blank => 'Please select an author'},
class: "form-control") %><br />
</div>
<%= f.submit 'Save Changes', class: "btn btn-primary" %>
<% end %>
</div>
</div>
Render form page (_form.html.erb)
<% if #book.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
<h2><%= pluralize(#book.errors.count, "error") %>
prohibited this entry from being saved:</h2>
<ul>
<% #book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
SHOW PAGE:
<div class="move">
<h1>Showing Book Titles:</h1>
</div><br />
<div class="row">
<% #books.each do |book| %>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-body">
<h2><%= book.title %></h2>
<h2><%= book.publisher %></h2>
<h2><%= book.pub_date %></h2>
<h2><%= book.author.name %></h2>
<h2><%= link_to "Edit", edit_path, class: "btn btn-primary" %>
</div>
</div>
</div>
<% end %>
Here is my Log telling me what is wrong:
Started GET "/edit" for ::1 at 2015-08-14 16:49:17 -0400
Processing by BooksController#edit as HTML
Rendered books/edit.html.erb within layouts/application (2.2ms)
Completed 500 Internal Server Error in 9ms (ActiveRecord: 0.0ms)
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
3: <div class="row">
4: <div class="col-md-6 col-md-offset-3">
5:
6: <%= form_for(#book) do |f| %>
7: <%= render 'form' %>
8:
9: <div class="form-group">
app/views/books/edit.html.erb:6:in `_app_views_books_edit_html_erb___525891009649529081_70260522100960'
I will say that I have deleted the first 14 books from my data base and so the first book start on ID 14. Not sure if that matters.
Finally, I have tried adding all of these different instance variables to my controller in the edit method:
##book = Book.where(id: params[:id])
##book = Book.find_by_id(params[:id])
##book = Book.all
##book = Book.find_by_id(params[:id])
#book = Book.new(book_params)
#When I use the two below lines,
there are no error pages but create a new entry.
##book = Book.new
##authors = Author.all
Any Help will be appreciated! Thank you for your time!!!
This error means that the first argument to form_for is a nil value (in this case #book). Most of the times I've seen this, it's due to malformed controller actions, but that doesn't look to be the case here. From what I can tell, it's one of two things:
You're trying to edit a Book that doesn't exist. Do a .nil? check on it before deciding to render the form, and render an error message (or redirect) instead.
Your routes are broken, and the edit action is not rendering the edit view. This is most likely not the case.
EDIT:
After updating with your template for show, this looks like your problem:
<%= link_to "Edit", edit_path, class: "btn btn-primary" %>
I see two problems with this (though I'll need to see the output of rake routes to verify). Firstly, you need to pass an argument to the edit path (without them, where would your params come from?). Secondly, the default route for this would be edit_book_path.
Try this:
<%= link_to "Edit", edit_book_path(book), class: "btn btn-primary" %>
Assuming book ID 14 is in your database, you should be able to navigate to localhost:3000/books/14/edit if you created it with something like resources :books (documentation here). If this doesn't work, either your routes are not defined correctly or book with ID 14 does not exist in your database.
On your show view, change the link_to line to:
<%= link_to 'Edit', edit_book_path(book), class: "btn btn-primary" %>
So two changes:
Again, assuming book is a Restful resource, when you run rake_routes, you should see the path to edit is edit_book_path.
You need to pass the book instance with the path so Rails knows which object you wish to edit.
I found the correct syntax here.
Hope this helps.

How to get parameters value in model from views form in rails?

Here is my new.html.erb
<%= form_for :simulation, url: simulations_path do |f| %>
<div class="form-group">
<%= f.label :Name %>
<div class="row">
<div class="col-sm-2">
<%= f.text_field :name, class: 'form-control' %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :'Rendering Option' %>
<div class="Dropdown">
<div class="col-sm-4">
<%= select_tag(:is_random, options_for_select([['Random', true], ['No Opinion', false]], selected: :is_random )) %>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<%= f.submit 'Submit', class: 'btn btn-primary' %>
</div>
simulations_controller.rb
class SimulationsController < ApplicationController
def index
#simulations = Simulation.all
end
def new
end
def create
#simulation = Simulation.new(simulation_params)
#simulation.save
redirect_to #simulation
end
def show
#simulation = Simulation.find(params[:id])
end
end
Simulation.rb (Model class)
class Simulation < ActiveRecord::Base
belongs_to :user
end
Schema.rb
create_table "simulations", force: :cascade do |t|
t.string "name"
t.boolean "is_random"
end
I am not able to set the :is_random value in database while rest is fine. What I am doing wrong here? I checked the value in sqlite database and there was null entry in is_random column.
You need to permit attributes while doing mass assignment. You could write it as :
<%= f.select(:is_random, options_for_select([['Random', true], ['No Opinion', false]], selected: :is_random )) %>
or
<%= select_tag("simulations[:is_random]", options_for_select([['Random', true], ['No Opinion', false]], selected: :is_random )) %>
With your syntax, the value is inside the params hash as {..., is_random: true,..}, that's why inside the strong parameter filtering method you are not getting it. If you use now the suggested solutions, you will get it the value inside the params hash like {..., simulations: { is_random: true,..}, ...}.
You can inspect all these from the the development.log file, while making the request.
You need to use form object select method like bellow:
<%= f.select(:is_random, options_for_select([['Random', true], ['No Opinion', false]], selected: :is_random )) %>
Using f.select (suggested above) should fix your problem. If you look at the generated html, you will see this field with a name of "is_random". It should be "simulations[is_random]". When you pull the form field values from the params object like this params[:simulations] all form fields with names in the form of "simulations[name]" will be included. Using the form builder object names the form fields correctly.
Hope this helps!
You can also use <%= debug params %> to inspect what's in params, it's very helpful.

How to access hidden_field in controller in Ruby on rails

Question: How to access hidden field value post_id from file view/comments/_comment.html.erb and use it in controllers/dashboards_controller.rb?
- there are 2 controllers - dashboard and comments, and using gem act_as_commentable_with_threading
Now I get: ActiveRecord::RecordNotFound in DashboardsController#index Couldn't find Post without an ID
config/routes.rb
resources :comments, :only => [:create, :destroy]
controllers/dashboards_controller.rb
class DashboardsController < ApplicationController
def index
#post = Post.new
#user = current_user
#newest_users = User.newest_players
#feed_posts = Post.paginate(:page => params[:page], :per_page => 8)
#last_clubs = Club.last_clubs
#commented_post = Post.find(params[:post_id])
# trying to access params from view/comments/_comment.html.erb
# comments is another controller...
# do other operations with #commented_post
#comments = #commented_post.comment_threads.order('created_at desc')
#new_comment = Comment.build_from(#commented_post, current_user, '')
end
end
view/comments/_comment.html.erb
Add comment
place for a comment form
<div class="comment-form">
<%= form_for :comment, :remote => true do |f| %>
<%=f.hidden_field 'post_id', post.id %>
# need to use this value in dasboard controller
<%=f.text_field :body %>
<% end %>
</div>
view/dashboards/_feed_post.html.erb
<ul class="post-items">
<%if #feed_posts.any? %>
<% #feed_posts.each do |post| %>
<li>
<span class="image"><%= image_tag post.image.url(:message) if post.image?%></span>
<span class="content"><%= post.text_html %></span>
<span class="tags">Tags:<%= post.tag_list %></span>
<span class="meta">
Posted <%= time_ago_in_words(post.created_at) %> ago.
| <%= post.user.full_name %>
</span>
<%= render 'comments/form' ,:locals => { :comment => #new_comment, :post_id => post.id } %>
<%= render 'comments/comment', :collection => #comments, :as => :comment, :post_id => post.id %>
</li>
<% end %>
<% end %>
</ul>
view/dashboards/index
<div class="row">
<div class="span7">
<!--form for creating a new post-->
<section>
<%= render :template => 'posts/new' %>
</section>
<!--dashboard feed_post-->
<section>
<%= render :partial => 'dashboards/feed_post' %>
</section>
</div>
you are using f.hidden_field so you will get
<%=f.hidden_field 'post_id', post.id %>
will create following html ref hidden_field
<input type="hidden" id="comment_post_id" name="comment[post_id]" value="#{comment.post_id}" />
so you can access this as following in your controller
params[:comment][:post_id]
so use following instead
#commented_post = Post.find(params[:comment][:post_id])
if you want 'post_id' in params[:post_id] use hidden_field_tag like following
<%= hidden_field_tag 'post_id', post.id %>

Resources