NoMethodError in Statuses#new - ruby-on-rails

I'm currently building this website in college for fun. My hope is that it will help the education system. Anyways, I'm still trying to figure out rails. I just set up the devise gem with no problem. However, when I click post a new status it gives me this error:
NoMethodError in Statuses#new
Showing /Users/wyatt/Network/netbook/app/views/statuses/_form.html.erb where line #16 raised:
undefined method `user_name' for #<Status:0x00000101ec36d0>
Extracted source (around line #16):
13:
14: <div class="field">
15: <%= f.label :user_name %><br />
16: <%= f.text_field :user_name %>
17: </div>
18: <div class="field">
19: <%= f.label :content %><br />
So here's what my form looks like:
<%= form_for(#status) do |f| %>
<% if #status.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#status.errors.count, "error") %> prohibited this status from being saved:</h2>
<ul>
<% #status.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_name %><br />
<%= f.text_field :user_name %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's my controller
class StatusesController < ApplicationController
# GET /statuses
# GET /statuses.json
def index
#statuses = Status.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #statuses }
end
end
# GET /statuses/1
# GET /statuses/1.json
def show
#status = Status.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #status }
end
end
# GET /statuses/new
# GET /statuses/new.json
def new
#status = Status.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #status }
end
end
# GET /statuses/1/edit
def edit
#status = Status.find(params[:id])
end
# POST /statuses
# POST /statuses.json
def create
#status = Status.new(params[:status])
respond_to do |format|
if #status.save
format.html { redirect_to #status, notice: 'Status was successfully created.' }
format.json { render json: #status, status: :created, location: #status }
else
format.html { render action: "new" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# PUT /statuses/1
# PUT /statuses/1.json
def update
#status = Status.find(params[:id])
respond_to do |format|
if #status.update_attributes(params[:status])
format.html { redirect_to #status, notice: 'Status was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
# DELETE /statuses/1
# DELETE /statuses/1.json
def destroy
#status = Status.find(params[:id])
#status.destroy
respond_to do |format|
format.html { redirect_to statuses_url }
format.json { head :no_content }
end
end
end

From looking at it, it seems you're wanting to append a user_name to a status
Error
Your error basically means you don't have a user_name column in your statuses data table. The basic fix will be to create a migration to add a user_name column to your statuses db:
$ rails generate migration AddUserNameToStatuses
#db/migrations/AddUserNameToStatuses.rb
class AddUserNameToStatuses < ActiveRecord::Migration
def change
add_column :statuses, :user_name, :string
end
end
$ rake db:migrate
Fix
I would actually ditch that, and do this:
#app/models/status.rb
Class Status < ActiveRecord::Base
belongs_to :user #-> you need user_id column in statuses db
delegate :name, to: :user, prefix: true
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :statuses
end
This will allow you to remove the references to user_name from your form - as any #status will be associated with a user
You'd then be able to use the .delegate() method to call user_name in statuses

Related

Difficulties with Nested Forms in Rails 6.1.3.2

I’m working on a project that will utilize nested forms that incorporates Rails 6.1.3 and Bootstrap 5.1.2.
I’m having difficulty getting the nested form feature to work.
Project GitHub: cjmccormick88/testapp-nested
There are two models: client and shipping address.
Client accepts nested attributes for the shipping address model. A client can have many shipping addresses.
Authentication is being handled by Devise. Bootstrap is used for styling. Audited is used for audit trail.
Clients Controller
class ClientsController < ApplicationController
before_action :set_client, only: %i[ show edit update destroy ]
# GET /clients or /clients.json
def index
#clients = Client.all
end
# GET /clients/1 or /clients/1.json
def show
end
# GET /clients/new
def new
#client = Client.new
#client.shipping_addresses.build
end
# GET /clients/1/edit
def edit
end
# POST /clients or /clients.json
def create
#client = Client.new(client_params)
#client.shipping_addresses.build(client_params[:shipping_addresses_attributes])
#client.save
respond_to do |format|
if #client.save
format.html { redirect_to #client, notice: "Client was successfully created." }
format.json { render :show, status: :created, location: #client }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1 or /clients/1.json
def update
respond_to do |format|
if #client.update(client_params)
format.html { redirect_to #client, notice: "Client was successfully updated." }
format.json { render :show, status: :ok, location: #client }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
# DELETE /clients/1 or /clients/1.json
def destroy
#client.destroy
respond_to do |format|
format.html { redirect_to clients_url, notice: "Client was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
#client = Client.find(params[:id])
end
# Only allow a list of trusted parameters through.
def client_params
params.require(:client).permit(:client_name, shipping_addresses_attributes: [:id, :address_line1, :address_line2, :city, :state, :country])
end
end
Client Model
class Client < ApplicationRecord
audited
has_many :shipping_addresses, :inverse_of => :client, autosave: true
accepts_nested_attributes_for :shipping_addresses
end
Shipping Address Model
class ShippingAddress < ApplicationRecord
audited
belongs_to :client
validates :client, :presence => true
end
Client View Form Partial
<%= form_with(model: client) do |form| %>
<% if client.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(client.errors.count, "error") %> prohibited this client from being saved:</h2>
<ul>
<% client.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :client_name %>
<%= form.text_field :client_name %>
</div>
<%= form.fields_for #client.shipping_addresses.build do |s| %>
<div class="field">
<%= s.label :address_line1, 'Address Line 1' %>
<%= s.text_field :address_line1 %>
</div>
<div class="field">
<%= s.label :address_line2, 'Address Line 2' %>
<%= s.text_field :address_line2 %>
</div>
<div class="field">
<%= s.label :city, 'City' %>
<%= s.text_field :city %>
</div>
<div class="field">
<%= s.label :state, 'State' %>
<%= s.text_field :state %>
</div>
<div class="field">
<%= s.label :country, 'Country' %>
<%= s.text_field :country %>
</div>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
In addition, there is a controller for shipping addresses if someone chooses to view those pages on their own.
Shipping Addresses Controller
class ShippingAddressesController < ApplicationController
before_action :set_shipping_address, only: %i[ show edit update destroy ]
# GET /shipping_addresses or /shipping_addresses.json
def index
#shipping_addresses = ShippingAddress.all
end
# GET /shipping_addresses/1 or /shipping_addresses/1.json
def show
end
# GET /shipping_addresses/new
def new
#shipping_address = ShippingAddress.new
end
# GET /shipping_addresses/1/edit
def edit
end
# POST /shipping_addresses or /shipping_addresses.json
def create
#shipping_address = ShippingAddress.new(shipping_address_params)
respond_to do |format|
if #shipping_address.save
format.html { redirect_to #shipping_address, notice: "Shipping address was successfully created." }
format.json { render :show, status: :created, location: #shipping_address }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #shipping_address.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shipping_addresses/1 or /shipping_addresses/1.json
def update
respond_to do |format|
if #shipping_address.update(shipping_address_params)
format.html { redirect_to #shipping_address, notice: "Shipping address was successfully updated." }
format.json { render :show, status: :ok, location: #shipping_address }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #shipping_address.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shipping_addresses/1 or /shipping_addresses/1.json
def destroy
#shipping_address.destroy
respond_to do |format|
format.html { redirect_to shipping_addresses_url, notice: "Shipping address was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shipping_address
#shipping_address = ShippingAddress.find(params[:id])
end
# Only allow a list of trusted parameters through.
def shipping_address_params
params.require(:shipping_address).permit(:address_line1, :address_line2, :city, :state, :country, :client_id)
end
end
Behavior of the Application
The application accepts the entry of the client form and it manipulates the model for the shipping address; however, the only entry in the table on each row is the client_id value for the client foreign key. It is not committing the other components of the hash into the table.
Screen Display
Things Tried
I've tried the application posted on GitHub at stevepolitodesign/rails-nested-form-app.
I've tried a suggestion made from a similar post on rails forum: difficulties-with-nested-form-implementation-rails-6-1-3/78776/3.
I've gone through as much documentation as I can track down on the standard rails guides for nested forms.
Results from all of these did not yield good results. Item # 1 was a decent app in terms of the pathway it takes; however, when you are using bootstrap it does not seem to work. It could be that the code there has to be modified some to allow that functionality. So far, any posts made for a request regarding bootstrap with that design have not yielded fruit.
Scope
I'm looking to understand the problem that is happening and/or find a better way to accomplish this function that cooperates well with Bootstrap use.

Rails 4 Nested Model : Not working

I was trying to work with simple nested models & forms but have failed eventually. I don't understand what wrong am I doing? Trying to implement simple nested model. A parent having many child. Can anyone please help me out. Thanks.
Here are the models:
parent.rb
class Parent < ActiveRecord::Base
has_many :childs
accepts_nested_attributes_for :childs
end
child.rb
class Child < ActiveRecord::Base
belongs_to :parent
end
parents_controller.rb
class ParentsController < ApplicationController
before_action :set_parent, only: [:show, :edit, :update, :destroy]
# GET /parents
# GET /parents.json
def index
#parents = Parent.all
end
# GET /parents/1
# GET /parents/1.json
def show
end
# GET /parents/new
def new
#parent = Parent.new
#parent.childs.new
end
# GET /parents/1/edit
def edit
end
# POST /parents
# POST /parents.json
def create
#parent = Parent.create(parent_params)
respond_to do |format|
if #parent.save
format.html { redirect_to #parent, notice: 'Parent was successfully created.' }
format.json { render :show, status: :created, location: #parent }
else
format.html { render :new }
format.json { render json: #parent.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /parents/1
# PATCH/PUT /parents/1.json
def update
respond_to do |format|
if #parent.update(parent_params)
format.html { redirect_to #parent, notice: 'Parent was successfully updated.' }
format.json { render :show, status: :ok, location: #parent }
else
format.html { render :edit }
format.json { render json: #parent.errors, status: :unprocessable_entity }
end
end
end
# DELETE /parents/1
# DELETE /parents/1.json
def destroy
#parent.destroy
respond_to do |format|
format.html { redirect_to parents_url, notice: 'Parent was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_parent
#parent = Parent.find(params[:id])
end
def parent_params
params.require(:parent).permit(:name, childs_attributes: [:name])
end
end
parent form.html.erb
<%= form_for(#parent) do |f| %>
<% if #parent.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#parent.errors.count, "error") %> prohibited this parent from being saved:</h2>
<ul>
<% #parent.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label 'Parent name' %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for :child do |c| %>
<div class="field">
<%= c.label 'Child Name' %><br>
<%= c.text_field :name %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The parent is getting created but the child is not. The child table has parent_id for associating both models.
Thanks in advance
I believe the plural of child is not childs, but children, and Rails knows this. You need to change your has_many association accordingly.
EDIT: As #pavan pointed out, change all the occurences in your code, not only the association.

HABTM Association Build

I need propagate this values in :departaments_products table: , but I received the error:
I'm using Rails 4
NoMethodError in Products#new
undefined method `departament_id' for #<Product:0x007f916d35d648>
view.html.erb:
<%= form_for(#product) do |f| %>
<% if #product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% #product.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>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field :price %>
</div>
<%= f.collection_select(:departament_id, Departament.all, :id, :name, {:include_blank => true}) %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Products_controller:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
#product = Product.find( params[:id] )
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Produto criado com sucesso' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :price)
end
end
Models:
class Departament < ActiveRecord::Base
has_and_belongs_to_many :products
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :departaments
end
Migration:
class AddProductsAndDepartaments < ActiveRecord::Migration
def change
create_table :departaments_products do |t|
t.references :product, :departament
end
end
end
As its a HABTM association, logically you should be selecting multiple departament_ids for a single product. That said, you should include multiple: true option in the collection_select for departament_ids (Notice departament_ids in plural) in your view code:
<%= f.collection_select(:departament_ids, Departament.all, :id, :name, {include_blank: true}, {multiple: true}) %>
Currently, you are accessing it as departament_id (Notice singular) BUT as per HABTM association you get a method named departament_ids (Notice plural) and NOT departament_id which is why you receive error as NoMethodError in Products#new undefined method 'departament_id'
Once you are done with this change, you need to permit the departament_ids field in ProductsController as below:
def product_params
params.require(:product).permit(:name, :price, :departament_ids => [])
end
:departament_ids => [] is used because multiple selection is allowed for departament_ids and so you would receive it as an Array in params hash upon form submission.
Try departament_ids
For has_many => departament_ids
For has_one => departament_id

acts_as_taggable issue - Everything looks almost fine

I have just followed step by step this other question, but my app is still giving me some errors regarding tagging (rails 4)
Error that Im experiencing is: Desktop/hack/app/controllers/jacks_controller.rb:85: syntax error, unexpected end-of-input, expecting keyword_end end ^
I have already re-intended as suggested in the chat, but nothing changed.
Code for reference
I have no associations between my models, (in the link that I have referred, there are associations)
jack form
<%= form_for(#jack) do |f| %>
<% if #jack.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#jack.errors.count, "error") %> prohibited this jack from being saved: </h2>
<ul>
<% #jack.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :tag_list, "Tags (separated by comma)" %><br>
<%= f.text_field :tag_list %>
</div>
<div class="field">
<%= f.label :picture %><br>
<%= f.text_field :picture %>
</div>
<div class="actions">
<%= f.submit %>
jack.rb
class Jack < ActiveRecord::Base
acts_as_taggable_on :tags
end
Routes
Rails.application.routes.draw do
get 'tagged/index'
root :to => redirect('/jacks')
get 'about' => "about#info"
get 'submit' => "jacks#create"
resources :jacks
match 'tagged', to: 'jacks#tagged', :as => 'tagged', via: 'get'
resources :users
jack active helper
module JacksHelper
include ActsAsTaggableOn::TagsHelper
end
And controller
class JacksController < ApplicationController
before_action :set_jack, only: [:show, :edit, :update, :destroy]
# GET /jacks
# GET /jacks.json
def index
if params [:tag]
#jacks = Jack.tagged_with(params[:tag])
else
#jacks = Jack.all
end
# GET /jacks/1
# GET /jacks/1.json
def show
end
# GET /jacks/new
def new
#jack = Jack.new
end
# GET /jacks/1/edit
def edit
end
# POST /jacks
# POST /jacks.json
def create
#jack = Jack.new(jack_params)
respond_to do |format|
if #jack.save
format.html { redirect_to #jack, notice: 'Jack was successfully created.' }
format.json { render :show, status: :created, location: #jack }
else
format.html { render :new }
format.json { render json: #jack.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /jacks/1
# PATCH/PUT /jacks/1.json
def update
respond_to do |format|
if #jack.update(jack_params)
format.html { redirect_to #jack, notice: 'Jack was successfully updated.' }
format.json { render :show, status: :ok, location: #jack }
else
format.html { render :edit }
format.json { render json: #jack.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jacks/1
# DELETE /jacks/1.json
def destroy
#jack.destroy
respond_to do |format|
format.html { redirect_to jacks_url, notice: 'Jack was successfully destroyed.' }
format.json { head :no_content }
end
end
def tagged
if params[:tag].present?
#jacks = Jack.tagged_with(params[:tag])
else
#jacks = Jack.postall
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_jack
#jack = Jack.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def jack_params
params.require(:jack).permit(:title, :description, :picture, :tag_list)
end
end
index method is missing an 'end'
def index
if params[:tag]
#jacks = Jack.tagged_with(params[:tag])
else
#jacks = Jack.all
end
end

undefined method `model_name' for NilClass:Clas

I am getting an error in Rails 3.2 with devise - my view is saying undefined method on line 1 below (user). This view is an edit profile page for logged in users.
So far I've tried changing this to current_user and defining that in my controller which I've provided below, but that did not work.
My only other suspicion is that form_for is not appropriate to use on this page?
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :username %><br>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :firstname %><br>
<%= f.text_field :firstname %>
</div>
<div class="field">
<%= f.label :lastname %><br>
<%= f.text_field :lastname %>
My controller... (as I said I tried current_user)
class UsersController < ApplicationController
def current_user
#current_user ||= User.find(session[:user_id])
end
def find
#user = User.new
end
def show
#user = User.find(params[:id])
end
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:username, :firstname, :dateofbirth, :lastname, :gender, :location, :email, :password)
end
end
Devise comes with a current_user helper method. You probably don't want to override that, so I'd recommend removing that method from your controller. In one of my apps I allow users to edit their info and this is my edit method:
def edit
#user = current_user
end

Resources