So I have a model GeneralCourses that I want to update from a controller Courses. I want to be able to add and edit entries in the model GenralCourses.
The issue I am having now is that when I want to submit the form it tells me:
No route matches [POST] "/courses/create"
courses_controller:
class CoursesController < ApplicationController
def new
#course = GeneralCourse.new
end
def create
#course = GeneralCourse.new(contact_params)
if #course.save
flash[:success] = "Course created"
redirect_to new_course_path
else
flash[:danger] = "Announcement not uploaded"
redirect_to new_course_path
end
end
def update
end
private
def contact_params
params.require(:general_course).permit(:course_code, :course_title, :course_unit, :course_desc)
end
end
courses form:
<%= form_for '/courses/create', method: :POST do |f| %>
with the form fields
<%= end %>
routes.rb:
Rails.application.routes.draw do
devise_for :admins
devise_for :staffs
devise_for :students
resources :courses
resources :announcements
resources :school_calenders
resources :pages
get '/stud/timetable' => 'pages#timetable'
get '/login' => 'pages#login'
get '/stud/announcement' => 'pages#ann'
root 'pages#home'
end
Given that it looks like you're using conventional routes for courses, you should be able to do:
<%= form_for courses_path do |f| %>
... with the form fields
<% end %>
Now, given also that in your new action, you did:
def new
#course = GeneralCourse.new
end
Then you really ought to be able to do:
<%= form_for #course do |f| %>
... with the form fields
<% end %>
Now, if you make your form into a partial, you should be able to use the same partial for your new action and your edit action.
Related
I'm receiving this error message:
No route matches [POST] "/users/9"
I'm trying to figure out a way to have the update method of one controller and use it in the view of a show method of another controller. This is what my route file looks like.
routes.rb
Rails.application.routes.draw do
root 'dashboards#index'
devise_for :users
resources :users, only: [:show]
patch '/users/:id' => 'companyinfos#update'
put '/users/:id' => 'companyinfos#update'
resources :dashboards, only: [:index]
end
I'm finding the correct companyinfo through the users controller
users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#companyinfo = Companyinfo.find(current_user.id)
end
end
and I'm saying to use this method inside of my company_info controller
companyinfos_controller.rb
class CompanyinfosController < ApplicationController
def update
#companyinfo = Companyinfo.find(current_user.id)
if #companyinfo.update(companyinfo_params)
flash[:notice] = "Saved ..."
else
flash[:alert] = "cannot save"
end
render 'edit'
end
private
def companyinfo_params
params.require(:companyinfo).permit(:CompanyStage)
end
end
and finally I'm using form_for to update it on users_path
show.html.erb
<%= form_for :companyinfo do |f| %>
<%= f.text_field :CompanyStage %>
<%= f.submit "save", class: "btn btn-success" %>
<% end %>
Updating the information in the database works fine when I update it through companyinfo/:id/edit but if I try to update it on another view such as users/:id I'm getting the error message above. What is the proper way to go about this?
UPDATE
Actually if I just do what the error message is telling me it works. Miracle right? Another question. Is there another way to have multiple routes from different controllers pointing to the same location? Or is this the best way?
Error says: No route matches [POST]
Update routes:
post '/users/:id' => 'companyinfos#update'
Or form method:
<%= form_for :companyinfo, method: :patch do |f| %>
I'm running into a NoMethodError in my Users#show when trying to include a form partial for submitting a task item (_form.html.erb). My other partial (_item.html.erb) is rendering properly. My item model and my user model are related to each other, user has_many :items, and item belongs_to :user.
Any and all help would be greatly appreciated!
Below is my routes.rb
Rails.application.routes.draw do
get 'welcome/index'
get 'welcome/about'
root 'users#show'
resources :users do
resources :items, only: [:new, :create]
end
devise_for :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Below is my terminal output
ActionView::Template::Error (undefined method `items_path' for #<#<Class:0x007fefeca61dd0>:0x007fefeca58b18>
Did you mean? items_create_path):
1: <h4> Create a new to-do item </h4>
2:
3: <%= form_for #item do |f| %>
4: <%= f.label :name %>
5: <%= f.text_field :name, class: 'form-control', placeholder: "Enter task here" %>
Items Controller
class ItemsController < ApplicationController
def new
#item = Item.new
end
def create
#item = Item.new
#item.user = current_user
#item.name = params[:item][:name]
if #item.save
flash[:notice] = "Item saved"
redirect_to #item
else
flash.now[:alert] = "Item was not created, please try again."
render :new
end
end
end
Users Controller
class UsersController < ApplicationController
def show
if !current_user.nil?
#user = current_user
#item = Item.new
#items = #user.items
else
redirect_to new_user_registration_path
end
end
end
Users#show page
<h2> Your to-do list</h2>
<div class="col-md-8">
<div class='items'>
<%= render partial: "items/item", local: { item: #item} %>
</div>
</div>
<div class="col-md-8">
<div class='new-item'>
<%= render partial: "items/form", local: { item: #item } %>
</div>
</div>
In your routes.rb file, you have items defined as a nested resource. You can check all of your routes by running this command on your terminal: rake routes.
For your routes specifically, you say:
resources :users do
resources :items, only: [:new, :create]
end
This would give you routes for GET /users/:user_id/items/new and POST /users/:user_id/items. However, in your form, it looks like you're trying to do this: <%= form_for #item do |f| %>. You don't have a route defined for an item by itself. You'll need to supply a user as well.
Try this for your form:
<%= form_for [#user, #item] do |f| %>
And something like this in your ItemsController:
class ItemsController
def new
#user = current_user
#item = Item.new
end
end
Your items route is nested under users. therefore you have to pass both to the form_for - a user and an item.
Something like this will probably work:
<%= form_for(current_user, #item) do |f| %>
Working with nested routes and associations. I have a partial which creates a tenant, but after the creation it stays with the form rendered and the url changes to /tenants. Desired behavior is that it needs to redirect_to the show page. Routes are as follows:
Rails.application.routes.draw do
devise_for :landlords
authenticated :landlord do
root "properties#index", as: "authenticated_root"
end
resources :tenants
resources :properties do
resources :units
end
root 'static#home'
end
So far the properties and units work (and the landlord) Issue is with Tenants. Originally I had Tenants nested under units, but had issues there as well. Partial looks like this:
<%= form_for #tenant do |f| %>
<%= f.label "Tenant Name:" %>
<%= f.text_field :name %>
<%= f.label "Move-in Date:" %>
<%= f.date_field :move_in_date %>
<%= f.label "Back Rent Amount:" %>
$<%= f.text_field :back_rent %>
<%= f.button :Submit %>
<% end %>
<%= link_to "Cancel", root_path %>
Tenants Controller looks like this:
before_action :authenticate_landlord!
#before_action :set_unit, only: [:new, :create]
before_action :set_tenant, except: [:new, :create]
def new
#tenant = Tenant.new
end
def create
#tenant = Tenant.new(tenant_params)
if #tenant.save
redirect_to(#tenant)
else
render 'new'
end
end
def show
end
def edit
end
def update
if #tenant.update(tenant_params)
redirect_to unit_tenant_path(#tenant)
else
render 'edit'
end
end
def destroy
end
private
def set_property
#property = Property.find(params[:property_id])
end
def set_unit
#unit = Unit.find(params[:unit_id])
end
def set_tenant
#tenant = Tenant.find(params[:id])
end
def tenant_params
params.require(:tenant).permit(:name, :move_in_date, :is_late, :back_rent, :unit_id)
end
end
Models have associations:
class Tenant < ApplicationRecord
belongs_to :unit, inverse_of: :tenants
end
class Unit < ApplicationRecord
belongs_to :property, inverse_of: :units
has_many :tenants, inverse_of: :unit
end
Lastly the show#tenants in rake routes is:
tenant GET /tenants/:id(.:format) tenants#show
I have extensively searched for this topic, but haven't had any success. Any help is appreciated. Rails 5.1
The route you are showing near the end of your question:
tenant GET /tenants/:id(.:format) tenants#show
is not the tenants index; it is the individual tenants/show route. You can tell this because it includes :id, which means it will show you a specific tenant having that id.
Try running rake routes again. The index route should look like this:
tenants GET /tenants(.:format) tenants#index
If you want to return to the tenants index after creating or updating a Tenant record, then you need to specify that path in your TenantsController. In both the #create and #update actions, your redirect line (after if #tenant.save and if #tenant.update, respectively) should read:
redirect_to tenants_path
That will take you to the TenantsController, #index action.
In the alternative, if you want to return to the individual tenant show page, then instead change both of those redirects in the TenantsController in both the #create and #update actions to:
redirect_to tenant_path(#tenant)
That will take you to the TenantsController, #show action for the current #tenant.
I have a form then I tried to insert in the supplier profile model which are company name, address and description also this model associatd in the supplier model. There is no error but when I view the database the supplier id part has no data.
Supplierprofile model
belongs_to :supplier
Supplier model
has_one :supplierprofile
routes.rb
resources :supplierprofiles
resources :supplierunits
resources :suppliers do
resources :supplierprofiles
resources :supplierunits
end
resources :sessions, except: :show do
member do
delete 'logout'
get 'home'
get 'profile'
get 'setting'
end
end
SupplierProfile Controller
before_action :set_supplierprofile, only: [:new, :create, :show]
def new
#profile = #supplier.build_supplierprofile
end
def create
if #profile = #supplier.create_supplierprofile(profile_params)
respond_to do |format|
format.html { redirect_to home_session_url(session[:user_id]),
notice: "Profile Completed!" }
end
else
respond_to do |format|
format.html { render action: 'new' }
end
end
end
private
def set_supplierprofile
#supplier = Supplier.find(session[:user_id])
end
def profile_params
params.require(:supplierprofile).permit(:company_name, :address, :description)
end
_form.html.erb
<%= simple_form_for([#supplier, #profile]) do |f| %>
<%= f.input :company_name %>
<%= f.input :address %>
<%= f.text_area :description %>
<%= f.button :submit %>
<% end %>
Thank you!
I solved the problem.. The codes will to much long if I paste here. but I can discuss here the solution flow, when I try to redirect_to home_session_url(session[:user_id]) I forgot that there was a callback function that check_profile and it will create an instance supplierprofile then in the console there was an update query. So, the solution I created was redirect to different method called dashboard then boom. I'm just new to rails. Thank you!
I'm building an application that has a Keynote model and a Story model (as well as a User model that I implemented with Devise).
Keynotes have many Stories and a Story belongs to a Keynote.
I'm having problems creating new stories and I get the following error:
ActiveRecord::RecordNotFound in StoriesController#create
Couldn't find Keynote without an ID
The error happens on line 17 of stories_controller.rb which is
#keynote = Keynote.find(params[:keynote_id])
in the create method.
This is part of my stories_controller.rb
class StoriesController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
def index
#keynote = Keynote.find(params[:keynote_id])
#stories = #keynote.stories
end
def new
#keynote = Keynote.find(params[:keynote_id])
#story = #keynote.stories.build
end
def create
if user_signed_in?
#keynote = Keynote.find(params[:keynote_id])
#story = #keynote.current_user.stories.build(params[:story])
if #story.save
flash[:notice] = 'Question submission succeeded'
redirect_to keynote_stories_path
else
render :action => 'new'
end
end
end
This is my keynotes_controller.rb
class KeynotesController < ApplicationController
def index
#keynotes = Keynote.find :all, :order => 'id ASC'
end
def new
#keynote = Keynote.new
end
def show
#keynote = Keynote.find(params[:id])
end
def create
#keynote = Keynote.new(params[:keynote])
if #keynote.save
flash[:notice] = 'Keynote submission succeeded'
redirect_to keynotes_path
else
render :action => 'new'
end
end
end
Any help would be really appreciated.
Edit:
These are the Parameters when I try to create a new Story.
{"utf8"=>"✓",
"authenticity_token"=>"76odSpcfpTlnePxr+WBt36fVdiLD2z+Gnkxt/Eu1/TU=",
"story"=>{"name"=>"as"},
"commit"=>"Send"}
It looks like the ID for the Keynote is not being passed.
This is the view for StoriesController#new
<%= error_messages_for 'story' %>
<%= form_for #story do |f| %>
<p>
Question:<br />
<%= f.text_field :name %>
</p>
<p>
<%= submit_tag "Ask" %>
</p>
<% end %>
This is what I have in my routes.rb file:
get "keynotes/index"
get "users/show"
devise_for :users
get "votes/create"
get "stories/index"
resources :keynotes do
resources :stories
end
resources :stories do
get 'bin', :on => :collection
resources :votes
end
resources :users
root :to => 'keynotes#index'
I think this should do the trick:
<%= form_for #story do |f| %>
<%= hidden_field_tag 'keynote_id', #keynote.id %>
.
rest of the form stuff here
.
<% end %>
PS. Not sure if you will get the keynote_id in params[:keynote_id] or params[:story][:keynote_id] .. check out both.
NB: I think there would be a easier way to do it too, using fields_for or something similar, but I don't have access to a Rails setup at the moment to test that out.