I'm trying to create a stock market app and I have a button that is breaking my web app. My issue is with this bit of embedded ruby on my
show.html.erb page:
<%= render #stock %>
<div>
<%= link_to "Edit this stock", edit_stock_path(#stock) %> |
<%= link_to "Back to stocks", stocks_path %>
<%= button_to "Delete this stock", #stock, method: :delete %>
</div>
This#stock.destroy line is needed for removing entries for a user. The error rails throws:
Showing C:/stockmarketapp/app/views/stocks/show.html.erb where line #9 raised:
undefined method `destroy' for #<StockQuote::Stock:0x000001f7fc0aa780 #attribution="Data provided for free by IEX (https://iexcloud.io).",
#response_code=200, #avg_total_volume=2261555,
#calculation_price="close", #change=-0.36, #change_percent=-0.00331,
#close=108.41, #close_source="official", #close_time=1654286400058,
#company_name="BlackRock Institutional Trust Company N.A. - iShares Core High Dividend ETF", #currency="USD", #delayed_price=108.4,
#delayed_price_time=1654286390674, #extended_change=0, #extended_change_percent=0, #extended_price=108.41,
#extended_price_time=1654300800004, #high=108.93, #high_source="15
minute delayed price", #high_time=1654286395170, #iex_ask_price=nil,
#iex_ask_size=nil, #iex_bid_price=nil, #iex_bid_size=nil,
#iex_close=108.43, #iex_close_time=1654286330444,
#iex_last_updated=nil, #iex_market_percent=nil, #iex_open=108.81,
#iex_open_time=1654263316934, #iex_realtime_price=nil,
#iex_realtime_size=nil, #iex_volume=nil,
#last_trade_time=1654286394157, #latest_price=108.41,
#latest_source="Close", #latest_time="June 3, 2022",
#latest_update=1654286400058, #latest_volume=876363, #low=108.25,
#low_source="15 minute delayed price", #low_time=1654273215082,
#market_cap=13133871500, #odd_lot_delayed_price=108.395,
#odd_lot_delayed_price_time=1654286390033, #open=108.33,
#open_time=1654263000128, #open_source="official", #pe_ratio=nil,
#previous_close=108.77, #previous_volume=1062893,
#primary_exchange="NYSE ARCA", #symbol="HDV", #volume=876363,
#week52_high=110.91, #week52_low=91.09,
#ytd_change=0.07801100501710605, #is_us_market_open=false>
Extracted source (around line #9):78910
<%= link_to "Edit this stock", edit_stock_path(#stock) %> |
<%= link_to "Back to stocks", stocks_path %>
<%= button_to "Delete this stock", #stock.destroy, method: :delete %>
</div>
Rails.root: C:/stockmarketapp
Application Trace | Framework Trace | Full Trace
app/views/stocks/show.html.erb:9
These are my files related to #stock and #stock.destroy:
class StocksController < ApplicationController
before_action :set_stock, only: %i[ show edit update destroy ]
before_action :correct_user, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
#api = StockQuote::Stock.new(api_key: "pk_153e93f4bce64c3d87e7d4d3510153ed")
# GET /stocks or /stocks.json
def index
#stocks = Stock.all
end
# GET /stocks/1 or /stocks/1.json
def show
#stocks = Stock.all
end
# GET /stocks/new
def new
#stock = Stock.new
end
# GET /stocks/1/edit
def edit
end
# POST /stocks or /stocks.json
def create
#stock = Stock.new(stock_params)
respond_to do |format|
if #stock.save
format.html { redirect_to stock_url(#stock), notice: "Stock was successfully created." }
format.json { render :show, status: :created, location: #stock }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #stock.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /stocks/1 or /stocks/1.json
def update
respond_to do |format|
if #stock.update(stock_params)
format.html { redirect_to stock_url(#stock), notice: "Stock was successfully updated." }
format.json { render :show, status: :ok, location: #stock }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #stock.errors, status: :unprocessable_entity }
end
end
end
# DELETE /stocks/1 or /stocks/1.json
def destroy
#stock.destroy
respond_to do |format|
format.html { redirect_to stocks_url, notice: "Stock was successfully destroyed." }
format.json { head :no_content }
end
end
def correct_user
#ticker = current_user.stocks.find_by(id: params[:id])
redirect_to stocks_path, notice: "Not Autherized to edit this stock" if #ticker.nil?
end
private
# Use callbacks to share common setup or constraints between actions.
def set_stock
#stock = Stock.find(params[:id])
end
# Only allow a list of trusted parameters through.
def stock_params
params.require(:stock).permit(:ticker, :user_id)
end
end
Stock partial:
<% #stock= StockQuote::Stock.quote(stock.ticker) %>
<div id="<%= dom_id stock %>">
<p>
<strong>Ticker:</strong>
<%= #stock.symbol %>
</p>
<p>
<strong>Open</strong>
$<%= #stock.open %>
</p>
<p>
<strong>Price</strong>
$<%= #stock.latest_price %>
</p>
<p>
<strong>Close</strong>
$<%= #stock.close %>
</p>
<p>
<strong>Company Name</strong>
<%= #stock.company_name %>
</p>
<p>
<strong>Primary Exchange</strong>
<%= #stock.primary_exchange %>
</p>
<p>
<strong>Volume</strong>
<%= number_with_delimiter(#stock.volume, :delimiter => ',') %>
</p>
<p>
<strong>Market Cap</strong>
$<%= number_with_delimiter(#stock.market_cap, :delimiter => ',') %>
</p>
</div>
Github Repo: https://github.com/Maikkeru/Stockmarketapp
I assume that am wielding the stock object incorrectly but I don't know where that slipup is occurring. Thanks for your time.
Related
In ruby on rails i want to show user's articles. Here is my articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: %i[ show edit update destroy ]
before_action :authenticate_user!, except: [:index, :show ]
before_action :correct_user, only: [:edit, :update, :destroy]
# GET /articles or /articles.json
def index
#articles = Article.all
end
def myarticles
#articles = Article.all
end
# GET /articles/1 or /articles/1.json
def show
end
# GET /articles/new
def new
##article = Article.new
#article = current_user.article.build
end
# GET /articles/1/edit
def edit
end
# POST /articles or /articles.json
def create
##article = Article.new(article_params)
#article = current_user.article.build(article_params)
respond_to do |format|
if #article.save
format.html { redirect_to #article, notice: "Article was successfully created." }
format.json { render :show, status: :created, location: #article }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /articles/1 or /articles/1.json
def update
respond_to do |format|
if #article.update(article_params)
format.html { redirect_to #article, notice: "Article was successfully updated." }
format.json { render :show, status: :ok, location: #article }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# DELETE /articles/1 or /articles/1.json
def destroy
#article.destroy
respond_to do |format|
format.html { redirect_to articles_url, notice: "Article was successfully destroyed." }
format.json { head :no_content }
end
end
def correct_user
#article = current_user.article.find_by(id: params[:id])
#redirect_to friends_path, notice: "Not Authorized To Edit This Friend" if #friend.nil?
redirect_to articles_path, notice: "Not Authorized To Edit This Article" if #article.nil?
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
#article = Article.find(params[:id])
end
# Only allow a list of trusted parameters through.
def article_params
params.require(:article).permit(:title, :description, :paragraph, :image, :content, :user_id)
#params.require(:article).permit(:title, :description, :paragraph, :image, :content) eskisi
end
end
in views/articles i have myarticles.html.erb
and in routes i have get 'articles/myarticles'
in myarticles.html.erb i have the same code for show.html.erb(actually i want to show the articles that belongs to that user but i will add that later):
<p id="notice"><%= notice %></p>
<div style="justify-content: center;display: flex;" >
<div style="max-width:680px;width: 100%;" >
<%# <div class="container-{680px}"> %>
<br>
<h1>
<%= #article.title %>
</h1>
<p>
<%= #article.description %>
</p>
<%# <p style="justify-content: center;display: flex;" > %>
<p style="flex-direction: column;display: flex;" >
<%if #article.image.attached? %>
<%=image_tag #article.image ,class:"img-fluid"%>
<% end %>
</p>
<p>
<%= #article.content %>
</p>
<%#
<p>
<%= #article.paragraph %>
<%# </p> %>
<br>
<%= link_to 'Edit', edit_article_path(#article) ,class:"btn btn-secondary"%> |
<%= link_to 'Back', articles_path ,class:"btn btn-secondary"%>
</div>
</div>
But i got this message:
NoMethodError in Articles#myarticles
Showing C:/Users/oem/Desktop/blog/app/views/articles/myarticles.html.erb where line #8 raised:
undefined method `title' for nil:NilClass
<h1>
<%= #article.title %>
</h1>
In your controller actionmyarticles you declared #articles. But in the view you are using #article. #article is available in show where is declared with the before_action callback, but not in my articles.
You probably want to show a list of articles in myarticles view so you can do something like:
<%= #articles.each do |article| %>
<h1>
<%= article.title %>
</h1>
...and so on
<% end %>
I get this error when trying to show <%= #schedule.title %>, but when I do the same with <%= #lesson.title %> it is working fine for #lesson.
![undefined method `title' for nil:NilClass
]1
The flow is like this.
- A user signs up and creates a clinic, the clinic belongs to the user.
- A clinic has many practitioners and they belongs to the clinic.
- A practitioner has many lessons and schedules, and they belongs to the practitioner.
When I'm on the lesson show page, there is a link to a booking page. It's on this booking page that the error occours.
I know it's saying nil, but both lessons and schedules have been created for that specific practitioner.
Anybody knows why this is happening? I don't understand why I can access #lesson but not #schedule. Any help would be much appreciated.
routes.rb
resources :clinics do
resources :practitioners do
resources :lessons, :lesson_payments, :schedules do
resources :bookings do
end
end
end
end
schedules_controller.rb
class SchedulesController < ApplicationController
before_action :set_schedule, only: [:show, :edit, :update, :destroy]
# GET /schedules
# GET /schedules.json
def index
#schedules = Schedule.all
end
# GET /schedules/1
# GET /schedules/1.json
def show
end
# GET /schedules/new
def new
#schedule = Schedule.new
end
# GET /schedules/1/edit
def edit
end
# POST /schedules
# POST /schedules.json
def create
#schedule = Schedule.new(schedule_params)
respond_to do |format|
if #schedule.save
format.html { redirect_to clinic_practitioner_schedule_path(id: #schedule.id), notice: 'Schedule was successfully created.' }
format.json { render :show, status: :created, location: #schedule }
else
format.html { render :new }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /schedules/1
# PATCH/PUT /schedules/1.json
def update
respond_to do |format|
if #schedule.update(schedule_params)
format.html { redirect_to clinic_practitioner_schedule_path(#schedule), notice: 'Schedule was successfully updated.' }
format.json { render :show, status: :ok, location: #schedule }
else
format.html { render :edit }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# DELETE /schedules/1
# DELETE /schedules/1.json
def destroy
#schedule.destroy
respond_to do |format|
format.html { redirect_to clinic_practitioner_schedules_url, notice: 'Schedule was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_schedule
#schedule = Schedule.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def schedule_params
params.require(:schedule).permit(:title, :start, :end, :practitioner_id, :account_id)
end
end
bookings_controller.rb
class BookingsController < ApplicationController
before_action :set_lesson, only: [:new]
def new
#account = Account.new
#user = User.new
#patient = Patient.new
#booking = Booking.new
#lesson_payment = LessonPayment.new
#schedule = Schedule.find_by_id(params[:id])
end
def create
create_patient_charge
create_patient_account
#user = User.new(user_params)
#user.account_id = #account.id
respond_to do |format|
if #user.save
create_patient_profile
create_patient_booking
create_patient_lesson_payment
auto_login(#user)
UserMailer.new_signup_booking_admin(#user, #booking).deliver_later
UserMailer.new_signup_booking_client(#user, #booking).deliver_later
format.html { redirect_to dashboard_url, notice: 'Your account was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { redirect_back fallback_location: root_path, alert: 'An error occurred while sending this request.' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
def set_lesson
#lesson = Lesson.find(params[:lesson_id])
end
def user_params
params.require(:user).permit(:email, :password, :time_zone)
end
def create_patient_account
#account = Account.new()
#account.status = 'active'
#account.account = 'prefix-' + SecureRandom.hex(4)
#account.account_type = 'client'
#account.save
end
def create_patient_profile
#patient = Patient.new()
#patient.firstname = params[:user][:patient][:patient_first_name]
#patient.lastname = params[:user][:patient][:patient_last_name]
#patient.phone = params[:user][:patient][:patient_phone]
#patient.user_id = #user.id
#patient.account_id = #user.account_id
#patient.save
end
def create_patient_booking
#lesson = Lesson.find(params[:user][:booking][:lesson_id])
#booking = Booking.new()
#booking.lesson_id = params[:user][:booking][:lesson_id]
#booking.schedule_id = params[:user][:booking][:schedule_id]
#booking.patient_id = #patient.id
#booking.account_id = #user.account_id
#booking.title = #lesson.title
#booking.cost = #lesson.cost
#booking.status = 'Booked'
#booking.save
#schedule = Schedule.find(params[:user][:booking][:schedule_id])
#booking.practitioner_id = #schedule.practitioner_id
#booking.start = #schedule.start
#booking.refunded = 0
#booking.save
#schedule.title = 'Booked'
#schedule.save
end
def create_patient_lesson_payment
#lesson_payment = LessonPayment.new()
#lesson_payment.status = 'Paid'
#lesson_payment.date = Date.today
#lesson_payment.cost = #lesson.cost
#lesson_payment.service = #lesson.title
#lesson_payment.booking_id = #booking.id
#lesson_payment.account_id = #user.account_id
#lesson_payment.save
end
end
This is where I link to the booking page
show.html.erb
<p id="notice"><%= notice %></p>
<%= link_to new_clinic_practitioner_lesson_booking_path(:lesson_id => #lesson.id), class: "course-btn" do %><i class="fa fa-calendar-plus-o"></i> Book This Lesson<% end %>
<p>
<strong>Image:</strong>
<%= #lesson.image %>
</p>
<p>
<strong>Title:</strong>
<%= #lesson.title %>
</p>
<p>
<strong>Duration:</strong>
<%= #lesson.duration %>
</p>
<p>
<strong>Cost:</strong>
<%= #lesson.cost %>
</p>
<p>
<strong>Category:</strong>
<%= #lesson.category %>
</p>
<p>
<strong>Language:</strong>
<%= #lesson.language %>
</p>
<p>
<strong>Level:</strong>
<%= #lesson.level %>
</p>
<p>
<strong>Description:</strong>
<%= #lesson.description %>
</p>
<p>
<strong>Practitioner:</strong>
<%= #lesson.practitioner_id %>
</p>
<p>
<strong>Account:</strong>
<%= #lesson.account_id %>
</p>
<%= link_to 'Edit', edit_clinic_practitioner_lesson_path(#lesson) %> |
<%= link_to 'Back', clinic_practitioner_lessons_path %>
new.html.erb
<h1>New Booking</h1>
<%= render 'form', booking: #booking %>
<%= link_to 'Back', clinic_practitioner_lesson_bookings_path %>
_form.html.erb
<table class="table table-bordered">
<thead>
<tr>
<th>Slots In The User's Time Zone</th>
<th>Price</th>
<th>Service Provider</th>
<th>Booking Button</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= #lesson.title %></td>
<td><%= #schedule.title %></td>
</tr>
</tbody>
</table>
I am noticing that in you are initializing #schedule like this in your bookings_controller new method:
#schedule = Schedule.find_by_id(params[:id])
But, you don't have any params[:id] in your parameters that are:
{'clinic_id'=>'50','practitioner_id'=>'27','lesson_id'=>'15'}
This is why your #schedule is nil
Assuming, there is a has_many association between practitioner and schedule, and you want to display the title of first schedule of the practitioner, you can do it it like this:
#schedule = Schedule.find_by_practitioner_id(params[:practitioner_id])
Hello I have a nested database "processing" which belongst to "shopping_process". However I want somehow to see the messages, which are saved in processing. How can I do that? If I go to http://localhost:3000/processings/index the Error: Couldn't find Processing with 'id'=index appears. Has somebody an idea?
processings_controller.rb
class ProcessingsController < ApplicationController
before_action :set_processing, only: [:show, :edit, :update, :destroy]
# GET /processings
# GET /processings.json
def index
#processings = Processing.all
end
# GET /processings/1
# GET /processings/1.json
def show
end
# GET /processings/new
def new
#processing = Processing.new
end
# GET /processings/1/edit
def edit
end
# POST /processings
# POST /processings.json
def create
#processing = Processing.new(processing_params)
respond_to do |format|
if #processing.save
format.html { redirect_to #processing, notice: 'Processing was successfully created.' }
format.json { render :show, status: :created, location: #processing }
else
format.html { render :new }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /processings/1
# PATCH/PUT /processings/1.json
def update
respond_to do |format|
if #processing.update(processing_params)
format.html { redirect_to #processing, notice: 'Processing was successfully updated.' }
format.json { render :show, status: :ok, location: #processing }
else
format.html { render :edit }
format.json { render json: #processing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /processings/1
# DELETE /processings/1.json
def destroy
#processing.destroy
respond_to do |format|
format.html { redirect_to processings_url, notice: 'Processing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_processing
#processing = Processing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def processing_params
params.require(:processing).permit(:shopping_process_id, :shopping_list_id, :accepted, :responded, :message)
end
end
view/processings/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Processings</h1>
<table>
<thead>
<tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #Processing.all.each do |processing| %>
<tr>
<td><%= link_to 'Show', processing %></td>
<td><%= link_to 'Edit', edit_processing_path(processing) %></td>
<td><%= link_to 'Destroy', processing, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Processing', new_processing_path %>
models/processing.rb
class Processing < ApplicationRecord
# db associations
belongs_to :shopping_process
belongs_to :shopping_list
# validations
validates :shopping_list, :presence => true
end
Now here comes the code for the database "shopping_processes"
shopping_processes_controller.rb
class ShoppingProcessesController < ApplicationController
load_and_authorize_resource
layout 'shopping_process', only: [:shopper_show, :senior_show]
# GET /shopping_processes/1
# GET /shopping_processes/1.json
def show
end
# POST /shopping_processes
# POST /shopping_processes.json
def create
#shopping_process.status =nil
#shopping_process.processed = nil
puts params.inspect
respond_to do |format|
if #shopping_process.save
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully created.' }
format.json { render :show, status: :created, location: #shopping_process }
else
format.html { render :new }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_processes/1
# PATCH/PUT /shopping_processes/1.json
def update
respond_to do |format|
if #shopping_process.update(shopping_process_params)
format.html { redirect_to #shopping_process, notice: 'Shopping process was successfully updated.' }
format.json { render :show, status: :ok, location: #shopping_process }
else
format.html { render :edit }
format.json { render json: #shopping_process.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_processes/1
# DELETE /shopping_processes/1.json
def destroy
#shopping_process.destroy
respond_to do |format|
format.html { redirect_to shopping_processes_url, notice: 'Shopping process was successfully destroyed.' }
format.json { head :no_content }
end
end
def shopper_show
#shopping_process = ShoppingProcess.find(params[:id])
#users = {}
first = true
#shopping_process.shopping_lists.each do |shopping_list|
user = shopping_list.user
#users[user.id] = {color: (first ? 'blue' : 'yellow'), name: user.firstname + ' ' + user.lastname}
first = false
end
end
def senior_show
#shopping_process = ShoppingProcess.find(params[:id])
#shopping_process.shopping_lists.each do |shopping_list|
#if shopping_list.user == current_user
# #shopping_list = shopping_list
#end
#shopping_list = shopping_list
#to show the correct shopping list uncomment the block above and remove the declartion underneath it
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shopping_process
#shopping_process = ShoppingProcess.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def shopping_process_params
params.require(:shopping_process).permit(:user_id, :status, :appointed, :processed, :shopping_list_id, processings_attributes: [ :shopping_list_id, :message ])
end
end
views/shopping_processes/form.html.erb
<%= form_for(shopping_process) do |f| %>
<% if shopping_process.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(shopping_process.errors.count, "error") %> prohibited this shopping_process from being saved:</h2>
<ul>
<% shopping_process.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :appointed %>
<%= f.datetime_select :appointed %>
</div>
<div class="field">
<%= f.label :shopper %>
<%= f.text_field :user_id, value: current_user.id, :readonly => true%>
</div>
<div class="field">
<%= f.label :shopping_list_id %>
<%= f.select :shopping_list_id, ShoppingList.accessible_by(current_ability).map{ |sl| [sl.name, sl.id] } %>
</div>
<!-- SUB FORM FOR NESTED RESOURCE : PROCESSINGS -->
<%= f.fields_for :processings, #shopping_process.processings.build do |ff| %>
<div>
<%= ff.label :Begleiter %>
<%= ff.select :shopping_list_id, ShoppingList.all.map{ |sl| [sl.user.firstname, sl.id]} , {:prompt => true} %>
</div>
<div>
<%= ff.label :message %>
<%= ff.text_field :message%>
</div>
<% end %>
<!-- Submit-->
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I'm trying to create a has-many association within a ruby on rails app where a user has-many goals and a goal has-many steps
I can't seem to figure out how to link the creation of a Step for a certain Goal. I've been playing around with it for a while and looking around on here but haven't found a solution.
Below are my Goal_controller, Step_Controller, Step form, and Goal form
Goal Controller:
class GoalsController < ApplicationController
before_action :set_goal, only: [:show, :edit, :update, :destroy]
before_filter :authorize
# GET /goals
# GET /goals.json
def index
#goals = Goal.all
end
# GET /goals/1
# GET /goals/1.json
def show
#goal = Goal.find(params[:id])
session[:current_goal] = #goal.id
end
# GET /goals/new
def new
#goal = Goal.new
end
# GET /goals/1/edit
def edit
end
# POST /goals
# POST /goals.json
def create
#goal = current_user.goals.new(goal_params)
respond_to do |format|
if #goal.save
format.html { redirect_to #goal, notice: 'Goal was successfully created.' }
format.json { render :show, status: :created, location: #goal }
else
format.html { render :new }
format.json { render json: #goal.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /goals/1
# PATCH/PUT /goals/1.json
def update
respond_to do |format|
if #goal.update(goal_params)
format.html { redirect_to #goal, notice: 'Goal was successfully updated.' }
format.json { render :show, status: :ok, location: #goal }
else
format.html { render :edit }
format.json { render json: #goal.errors, status: :unprocessable_entity }
end
end
end
# DELETE /goals/1
# DELETE /goals/1.json
def destroy
#goal.destroy
respond_to do |format|
format.html { redirect_to goals_url, notice: 'Goal was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_goal
#goal = Goal.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def goal_params
params.require(:goal).permit(:Goal, :Description, :Date, :DueDate, :user_id)
end
end
Step Controller:
class StepsController < ApplicationController
#before_action :set_step, only: [:show, :edit, :update, :destroy]
before_filter :authorize
# GET /steps
# GET /steps.json
def index
#steps = Goal.find(params[:goal_id]).steps.all
end
def new
#step = Goal.find(params[:goal_id]).steps.new
end
# GET /steps/1
# GET /steps/1.json
def show
end
# GET /steps/1/edit
def edit
end
def create
#step = Goal.find(params[:goal_id]).steps.new(step_params)
respond_to do |format|
if #step.save
format.html { redirect_to #step, notice: 'Step was successfully created.' }
format.json { render :show, status: :created, location: #step }
else
format.html { render :new }
format.json { render json: #step.errors, status: :unprocessable_entity }
end
end
redirect_to(goal_steps_url(#goal))
end
def update
#step.update(step_params)
respond_to do |format|
if #step.update(step_params)
format.html { redirect_to #step, notice: 'Step was successfully updated.' }
format.json { render :show, status: :ok, location: #step }
else
format.html { render :edit }
format.json { render json: #step.errors, status: :unprocessable_entity }
end
end
end
# POST /steps
# POST /steps.json
def destroy
#step.destroy
respond_to do |format|
format.html { redirect_to steps_url, notice: 'Step was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_step
#step = Goal.find(params[:goal_id]).Step.find(params[:id])
end
def step_params
params.require(:step).permit(:requirement, :completionTime, :goal_id)
end
end
Step Form:
<%= form_for(#step) do |f| %>
<% if #step.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#step.errors.count, "error") %> prohibited this step from being saved:</h2>
<ul>
<% #step.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :requirement %><br>
<%= f.text_field :requirement %>
</div>
<div class="field">
<%= f.label :completionTime %><br>
<%= f.number_field :completionTime %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Goal Form:
<%= form_for(#goal) do |f| %>
<% if #goal.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#goal.errors.count, "error") %> prohibited this goal from being saved:</h2>
<ul>
<% #goal.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Goal %><br>
<%= f.text_field :Goal %>
</div>
<div class="field">
<%= f.label :Description %><br>
<%= f.text_area :Description %>
</div>
<div class="field">
<%= f.label :Date %><br>
<%= f.date_select :Date %>
</div>
<div class="field">
<%= f.label :DueDate %><br>
<%= f.date_select :DueDate %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It looks like you will be missing your goal_id when you submit your step creation form. You will need to store it either in a hidden field in your step form, or as part of the route (e.g. POST /goals/10/steps).
In my application I have stories and substories. Substories are nested inside stories and on the storiesindex.html.erb. I'm looping trough all the stories, and inside I'm looping through all the substories.
here is the code:
<% #stories.each do |story| %>
<%= story.title %>
<%= story.plot %>
<%= link_to 'Show', story_path(story) %>
<%= link_to 'Edit', edit_story_path(story) %>
<%= link_to "Delete", story_path(story), method: :delete, data: { confirm: "Are you sure?" } %>
<% story.substories.each do |substories| %>
<%= substories.title %>
<%= substories.subplot %>
<% end %>
<% end %>
<%= link_to 'New Story', new_story_path %>
This works fine, but I want to link to the edit page of each substory by passing the following argument inside the second loop:
<%= link_to 'Edit', edit_story_substory_path(substory.story, substory) %>
I get a NameError in Stories#index undefined local variable or method 'substory', however this work fine in the substories index.html.erb file.
I've also tried the following:
<%= link_to 'Edit', edit_story_substory_path(#substory.story, #substory) %>
for which I get a NoMethodError in Stories#index undefined method 'story' for nil:NilClass
Here are my routes models and controllers:
#routes.rb
resources :stories do
resources :substories
end
#story.rb
has_many :substories
#substory.rb
belongs_to :story
stories_controller.erb
before_action :set_story, only: [:show, :edit, :update, :destroy]
def index
#stories = Story.all
end
def show
#substories = Substory.where(story_id: #story.id).order("created_at DESC")
end
def new
#story = Story.new
end
def edit
end
def create
#story = Story.new(story_params)
respond_to do |format|
if #story.save
format.html { redirect_to root_path, notice: 'Story was successfully created.' }
format.json { render :show, status: :created, location: root_path }
else
format.html { render :new }
format.json { render json: root_path.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #story.update(story_params)
format.html { redirect_to root_path, notice: 'Story was successfully updated.' }
format.json { render :show, status: :ok, location: root_path }
else
format.html { render :edit }
format.json { render json: #story.errors, status: :unprocessable_entity }
end
end
end
def destroy
#story.destroy
respond_to do |format|
format.html { redirect_to stories_url, notice: 'Story was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_story
#story = Story.find(params[:id])
end
def story_params
params.require(:story).permit(:title, :plot)
end
substories_controller.erb
before_action :set_substory, only: [:show, :edit, :update, :destroy]
before_action :set_story
def index
#substories = Substory.all
end
def show
end
def new
#substory = Substory.new
end
def edit
end
def create
#substory = Substory.new(substory_params)
#substory.user_id = current_user.id
#substory.story_id = #story.id
if
#substory.save
redirect_to #story
else
render 'new'
end
end
def update
respond_to do |format|
if #substory.update(substory_params)
format.html { redirect_to root_path, notice: 'Story was successfully updated.' }
format.json { render :show, status: :ok, location: root_path }
else
format.html { render :edit }
format.json { render json: #story.errors, status: :unprocessable_entity }
end
end
end
def destroy
#substory.destroy
redirect_to root_path
end
private
def set_story
#story = Story.find(params[:story_id])
end
def set_substory
#substory = Substory.find(params[:id])
end
def substory_params
params.require(:substory).permit(:title, :subplot)
end
What am I missing?
<% story.substories.each do |substory| %>
<%= substory.title %>
<%= substory.subplot %>
<% if substory %>
<%= link_to 'Edit', edit_story_substory_path(substory.story, substory) %>
<% end %>
<% end %>
You just made a typo. #substory would work too if you declare it on your Stories#index