ActiveRecord::RecordNotFound - Product without an ID - ruby-on-rails

I am trying to create a review in my app however when I am doing the following in my controller:
def create
#product = Product.find(params[:product_id])
#review = #product.reviews.create(params[:review])
redirect_to product_path(product)
end
I get Couldn't find Product without an ID. I fill the form out and some where along the lines when it does the following line #product = Product.find(params[:product_id]) it cannot seem to find the product
routes
resources :products do
resource :reviews
end
products/show.html.erb
<%= form_for(#product.reviews.build) do |f| %>
<div class="field">
<%= f.label :title %>
<br/>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :author %>
<br/>
<%= f.text_field :author %>
</div>
<div class="field">
<%= f.label :content %>
<br/>
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.label :rating %>
<br/>
<%= f.number_field :rating %>
</div
<div class="actions">
<%= f.submit %>
</div>
<% end %>

change your form_for to
form_for [#product, #product.reviews.build] do |f|
this changes the action to /products/#product.id/reviews to match your nested route

Related

How to add custom fields in devise invitables in rails the custom fields is your name and phone number

Actually Ineed the exact code for this problem, I am working on it but face errors on it
From README
Here is an example of what your application controller might need to include in order to add these parameters to the invitation view:
class Users::InvitationsController < Devise::InvitationsController
before_action :configure_permitted_parameters
protected
# Permit the new params here.
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:invite, keys: %i[name phone])
end
end
Here is an example setting a User's name and phone for a custom invitation:
<%= form_for(resource, as: resource_name, url: invitation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<% resource.class.invite_key_fields.each do |field| -%>
<div class="field">
<%= f.label field %>
<%= f.text_field field %>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :phone %>
<%= f.text_field :phone %>
</div>
<div class="actions">
<%= f.submit t("devise.invitations.new.submit_button") %>
</div>
<% end %>

Nested routes form_for partial not working for new and edit actions - Rails 4

I used the generator to scaffold categories and questions.
my routes.rb
resources :categories do
resources :questions do
resources :choices, only: [:index]
end
end
my problem occurs when i try to add or edit a question.
here is my partial form, before you ask the relationship works ok.
<%= form_for [#question.category, #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 :question_type %><br>
<%= f.text_field :question_type %>
</div>
<div class="field">
<%= f.label :explanation %><br>
<%= f.text_field :explanation %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :category_id %><br>
<%= f.text_field :category_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
what must i change for it to work? for now i get,
undefined method `questions_path'
Try this
UPDATE
Controller
#category = Category.find(params[:category_id])
#question = #category.questions.new
_form
<%= form_for([#category, #question]) do |f| %>
Reference
You should pass parent and then build child for same for new object.
<%= form_for [#category, #category.questions.build] do |f| %>
To edit:
<%= form_for [#category, #category.questions.first_or_your_object] do |f| %>
Like this :
<% if #category.new_record? %>
<%= form_for [#category, #category.questions.build] do |f| %>
<% else %>
<%= form_for [#category, #category.questions.first_or_your_object] do |f|
<% else %>
Also add in your category model:
accepts_nested_attributes_for :questions
Add this line to your category.rb model file:
accepts_nested_attributes_for :questions
Also, in your controller:
#category = Category.find(params[:category_id])
#question = Question.new(category: #category)
and form:
<%= form_for([#category, #question]) do |f| %>

Rails 4 - Nested Object Won't Save

Note: I've read a couple posts similar to this. But non of the solutions answer my question
I have two objects, Bid and Moz. When I build my Bid object, everything seems to save okay, except for the Moz objects.
Model
class Bid < ActiveRecord::Base
belongs_to :user
has_many :mozs, :dependent => :destroy
accepts_nested_attributes_for :mozs, :allow_destroy => true
end
class Moz < ActiveRecord::Base
belongs_to :bid
end
Bids::Build Controllers
class Bids::BuildController < ApplicationController
include Wicked::Wizard
steps :intro, :problems, :solutions, :pricing
def show
#bid = Bid.find(params[:bid_id])
render_wizard
end
def update
#bid = Bid.find(params[:bid_id])
#bid.attributes = build_params
4.times { #bid.mozs.build } if step == steps.second
render_wizard #bid
end
def new
#bid = Bid.new
redirect_to wizard_path(steps.first, :bid_id => #bid.id)
end
def build_params
params.require(:bid).permit(:client_name, :intro, :prob1, :prob2, :prob3, :site_feel, :search_phrase, :page_score, :total_links,
:internal_links, :external_links, :competition, :complete, :user_id, :us_company, :philosophy_1,
:philosophy_2, :website_conclusions, :is_onsite_seo, :onsite_seo, :is_ongoing_seo, :ongoing_seo,
:is_ppc, :ppc, :is_social_media, :social_media, :is_google_places, :google_places, :is_adwords_express,
:adwords_express, moz_attributes: [:url, :id, :_destroy]
)
end
private
def finish_wizard_path
root_url
end
end
solutions.html.erb
<%= form_for (#bid), url: wizard_path do |f| %>
<% if #bid.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#bid.errors.count, "error") %> prohibited this bid from being saved:</h2>
<ul>
<% #bid.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if #bid.is_onsite_seo? %>
<div class="field">
<%= f.label :onsite_seo %><br>
<%= f.text_area :onsite_seo %>
</div>
<% end %>
<% if #bid.is_ongoing_seo? %>
<div class="field">
<%= f.label :ongoing_seo %><br>
<%= f.text_area :onsite_seo %>
</div>
<% end %>
<div class="field">
<%= f.label :ppc %><br>
<%= f.text_area :ppc %>
</div>
<div class="field">
<%= f.label :social_media %><br>
<%= f.text_area :social_media %>
</div>
<div class="field">
<%= f.label :google_places %><br>
<%= f.text_area :google_places %>
</div>
<div class="field">
<%= f.label :adwords_express %><br>
<%= f.text_area :adwords_express %>
</div>
<%= f.fields_for :mozs do |builder| %>
<%= render partial: "moz_fields", locals: {f: builder} %>
<% end %>
<%= link_to_add_association "Add URL", f, :mozs %>
<div class="actions">
<%= f.submit %>
or <%= link_to "skip this step", next_wizard_path %>
</div>
<% end %>
_moz_fields.html.erb
<div class="field fields">
<%= f.label :url, "Comparative URL" %><br>
<%= f.text_field :url %>
<%= f.hidden_field :destroy %>
<%= link_to_function "remove", "remove_fields(this)"%>
</div>
I don't understand why they won't save. In addition, I noticed something odd -- when I don't use a partial for the nested object and use the f form builder for the #bid object (as opposed to 'builder'), I get an error no method or variable :url, but a Moz object is saved (although, not with any of the desired attributes).
My opinion that you misspelled with permit attrbibutes hash, try to change moz_attributes to mozs_attributes.
params.require(:bid).permit(..., :mozs_attributes: [:url, :id, :_destroy])
If you send the parameter _destroy: 1 through your hidden field
<%= f.hidden_field :destroy %>
you instruct Rails to destroy the child moz object, or in your case, prevent it from being created.
As for the second part of your question, if you inline the partial from this
<%= f.fields_for :mozs do |builder| %>
<%= render partial: "moz_fields", locals: {f: builder} %>
<% end %>
to this
<%= f.fields_for :mozs do |builder| %>
<div class="field fields">
<%= f.label :url, "Comparative URL" %><br>
<%= f.text_field :url %>
<%= link_to_function "remove", "remove_fields(this)"%>
</div>
<% end %>
it won't work, because the model object for the scope f is your #bid, not moz. Bids have no url attribute, hence the error.
With the input fields being created in the wrong form builder scope, you did not actually transmit any attributes for your moz object, and so it was created blank. As a side effect, this also meant not sending the _destroy parameter, so the object was saved.
Instead, inline the partial like this (I renamed builder to moz for clarity):
<%= f.fields_for :mozs do |moz| %>
<div class="field fields">
<%= moz.label :url, "Comparative URL" %><br>
<%= moz.text_field :url %>
<%= link_to_function "remove", "remove_fields(this)"%>
</div>
<% end %>

Nested_form_for with field_for not working

my view is
<h3> Register New Items </h3>
<div class="row">
<div class="span2 offset4">
<%= nested_form_for #item_category, :url => items_path, :method => :post, :html => { :class => "item_category"} do |f| %>
<div><%= f.label :item_name %>
<%= f.text_field :item_name %></div>
</br>
<div>
<%= f.fields_for :item_companies do |f| %>
<%= f.label :company_name %>
<%= f.text_field :company_name %>
</div>
</br>
<%= f.fields_for :item_weights do |f| %>
<div>
<%= f.label :weight %>
<%= f.text_field :weight %>
</div>
</br>
<div>
<%= f.label :price %>
<%= f.text_field :price %>
</div>
<%end%>
<%end%>
<div><%= f.submit "Submit" %></div>
<% end %>
</div>
and controller
def new
#item_category = ItemCategory.new
item_company = #item_category.item_companies.build
item_company.item_weights.build
end
and when I have applied debugger in create action and I saw value of params[:item_category] and this is generated {"item_name"=>"iname", "item_companies_attributes"=>{"0"=>{"company_name"=>"cname", "item_weights_attributes"=>{"0"=>{"weight"=>"20kg", "price"=>"100"}}}}}
ItemCategory.new(params[:item_category])
generated error
ActiveModel::MassAssignmentSecurity::Error Exception: Can't mass-assign protected attributes: item_companies_attributes.
Where i am wrong and how to save value in three tables using this.
It seems that you forgot to add this piece of code in your ItemCategory model:
attr_accessible :item_companies_attributes
which will allow you to set these attributes.

Form_for generates resource path ending with '.1'

I have a resource called :school and when I call form_for(#school) it generates the form action:
/school.1
I'm new to all this so any clues as to why it's doing that would be much appreciated. Sleep deprived and heading for a deadline in 3 hours, arrrggg!
Thanks :)
routes.rb:
resource:school
school.rb:
<%= form_for(#school, :url => school_path) do |f| %>
<% if #school.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#school.errors.count, "error") %> prohibited this school from being saved:</h2>
<ul>
<% #school.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 :address1 %><br />
<%= f.text_field :address1 %>
</div>
<div class="field">
<%= f.label :address2 %><br />
<%= f.text_field :address2 %>
</div>
<div class="field">
<%= f.label :address3 %><br />
<%= f.text_field :address3 %>
</div>
<div class="field">
<%= f.label :town %><br />
<%= f.text_field :town %>
</div>
<div class="field">
<%= f.label :county %><br />
<%= f.text_field :county %>
</div>
<div class="field">
<%= f.label :postcode %><br />
<%= f.text_field :postcode %>
</div>
<div class="field">
<%= f.label :local_authority_id %><br />
<%= f.collection_select :local_authority_id, LocalAuthority.all, :id, :name %>
</div>
<% if current_user.person.primary_user? %>
<div class="field">
<%= f.label 'Are you happy for us to send you regular updates about VRH?' %><br />
<%= f.check_box :allow_contact %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
by using the singular resource method you are telling rails that only one of these objects exist, in your routes file I think you need to change your resource :school to...
resources :schools
If however you do want only one school then I think you will need to add the url option to form_for...
<% form_for(#school, :url => school_path) %>
Proposed solution for follow up questions...
I think what you need will be something like this...
# routes.rb
resources :users do
resources :schools
end
resources :schools
# app/controllers/schools_controller.rb
class SchoolsController < ApplicationController
def new
#user = User.find(params[:user_id])
#school = #user.build_school
end
def create
#user = User.find(params[:user_id])
#school = #user.build_school(params[:school])
if #school.save
# success...
else
# fail...
end
end
def edit
#school = School.find(params[:id])
end
def update
#school = School.find(params[:id])
if #school.update_attributes(params[:school])
# success
else
# fail
end
end
end
# app/views/schools/new.html.erb
<%= form_for([#user, #school]) do |f| %>
<!-- fields go here -->
<% end %>
# app/views/schools/edit.html.erb
<%= form_for([#user, #school]) do |f| %>
<!-- fields go here -->
<% end %>
I just had a similar issue with a singular profile resource in my routes.rb file:
resource :profile
It took me a few hours to find a solution so I decided to share it to save someone else the trouble.
I had to remove the "(.:format)" part of the route (shown when running "rake routes"), by specifying a specific format:
constraints :format => "html" do
resource :profile
end
I also had to add the :url option to form_for tags:
<% form_for(#profile, :url => profile_path) %>
and that worked.

Resources