I am using Rails 4.2 with Ruby 2.1.5
Here is my routes file:
Rails.application.routes.draw do
root to: "services#index"
resources :apis, only: [:new, :create]
resources :commons, path: "/self-care2/commonController" do
collection do
post :search, to: "commons#search"
end
end
end
Here is my rake routes result:
Prefix Verb URI Pattern Controller#Action
root GET / services#index
apis POST /apis(.:format) apis#create
new_api GET /apis/new(.:format) apis#new
search_commons POST /self-care2/commonController/search(.:format) commons#search
commons GET /self-care2/commonController(.:format) commons#index
POST /self-care2/commonController(.:format) commons#create
new_common GET /self-care2/commonController/new(.:format) commons#new
edit_common GET /self-care2/commonController/:id/edit(.:format) commons#edit
common GET /self-care2/commonController/:id(.:format) commons#show
PATCH /self-care2/commonController/:id(.:format) commons#update
PUT /self-care2/commonController/:id(.:format) commons#update
DELETE /self-care2/commonController/:id(.:format) commons#destroy
Here are some actions of controller:
def edit
#api = Api.find(params[:id])
end
def update
#api = Api.find(params[:id])
if #api.update(api_params)
flash[:info] = request.original_url + ".do?apiname=" + "#{#api.name}"
redirect_to root_path
else
#api.statuses.new
render :edit
end
end
def new
#api = Api.new
#status = #api.statuses.new
#status.descriptions.new
end
def create
#api = Api.new(api_params)
if #api.save
flash[:info] = request.original_url + ".do?apiname=" + "#{#api.name}"
redirect_to root_path
else
#api.statuses.new
render :new
end
end
And here is my edit template:
<%= form_for #api, :url => commons_path, :method => :patch do |f| %>
<div class="form-group">
<%= f.label :name, "API Name", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= f.text_field :name, class: "form-control" %>
</div>
</div>
<%= f.fields_for :statuses do |status| %>
<div class="form-group">
<%= status.label :name, "Status", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= status.text_field :name, class: "form-control" %>
</div>
</div>
<%= status.fields_for :descriptions do |description| %>
<div class="form-group">
<%= description.label :value, "Body", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= description.text_area :value, class: "form-control", rows: 12, cols: 65 %>
</div>
</div>
<% end %>
<% end %>
<%= f.submit("Edit Data", class: 'btn btn-primary col-sm-offset-2') %>
<%= link_to "Cancel", root_path, class: "btn btn-danger" %>
<% end %>
When I access to edit template, I can see old data and replace them with new data.
But show "No route matches [PATCH] "/self-care2/commonController" after I click submit button.
Anyone know what happen?
Since you update specific Api, shouldn't it be like:
<%= form_for #api, :url => common_path(#api.id), :method => :patch do |f| %>
Related
been banging my head on the table over this one. I have another nested form but this one is driving me crazy.
The error is:
TypeError in CompaniesController#create
no implicit conversion of Symbol into Integer
#company = Company.new(company_params)
The controller:
class CompaniesController < ApplicationController
layout 'welcome'
def new
#company = Company.new
end
def create
#company = Company.new(company_params)
if #company.save
flash[:notice] = "New company created successful."
redirect_to admin_accounts_path
else
flash.now[:alert] = "Creation failed, please try again"
render :new
end
end
private
def company_params
params.require(:company).permit(:name, :location, :users_attributes => [:email, :password])
end
end
On the new.html.erb:
<%= render partial: 'form', locals: { company: #company, users_attributes: :users_attributes } %>
This code looks exactly like another nested setup I have, but it works :p
I had read that sometimes changing the params from => to just having a semicolon works, but replacing the user_attributes => with a user_attributes: didn't change anything.
EDIT: form.html.erb
<%= form_for company, url: companies_path do |f| %>
<div class="col-12">
<div class="row">
<div class="col p-0 mr-3">
<div class="form-group">
Company <%= f.label :name %>
<%= f.text_field :name, :placeholder => 'Company name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :location %>
<%= f.text_field :location, :placeholder => 'Location', class: 'form-control' %>
</div>
</div>
<div class="col p-0">
<%= f.fields_for users_attributes do |user_f| %>
<div class="form-group">
<%= user_f.label :email %>
<%= user_f.text_field :email, :placeholder => 'Your Email Address', class: 'form-control' %>
</div>
<div class="form-group">
<%= user_f.label :password %>
<%= user_f.password_field :password, :placeholder => 'Password', class: 'form-control' %>
</div>
<% end %>
</div>
<div class="col-12 p-0">
<%= f.submit "Sign-Up", :class => 'btn btn-primary btn-block btn-lg' %>
</div>
</div>
</div>
<% end %>
Use users instead of users_attributes on the form.
Don't forget to define accepts_nested_attributes_for :users in model Company
## new.html.erb
<%= render partial: 'form', locals: { company: #company, users_attributes: :users } %>
I wonder why you didn't put :users into the form directly
Rails 5. keep getting the error that route could not be found. What did I do wrong here?
App/views/contacts/new.html.erb
<%= form_for "#contact" do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
routes.rb file
Rails.application.routes.draw do
root to: 'pages#home'
get '/about', to: 'pages#about'
resources :contacts
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to new_contact_path, notice: "Message sent."
else
redirect_to new_contact_path, notice: "Error occured."
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
contact.rb (model file, blank for now)
class Contact < ActiveRecord::Base
end
I can't figure out why. Thanks in advance.
You have quotes around your #contact variable in your form, try just using the plain #contact variable.
There are a few similar questions that exist to this, but I could not clearly understand the answer. I am trying to make a simple rails application with CRUD operations for a specific model. I am specifically having trouble with doing this using the form_for function for updating the record.
My routes.rb file:
Rails.application.routes.draw do
root 'main#index'
devise_for :users
resource :models
get 'main/index'
end
My models_controller.rb
class ModelsController < ApplicationController
def edit
#nc = Model.find(params[:id])
end
def update
#nc = Model.find(params[:id])
#nc.update(model_params)
if #nc.save
flash[:success] = 'Changes saved.'
redirect_to model_path
else
flash[:error] = #nc.errors.empty? ? 'Error' : #nc.errors.full_messages.to_sentence
render :action => :edit
end
end
def model_params
params.require(:model).permit(:first_name, :last_name)
end
end
and finally my model/edit.html.erb
<%= form_for #nc do |nc| %>
<div class='container-fluid'>
<form role='form'>
<div class='row'>
<div class='col-md-6'>
<div class='form-group'>
<%= nc.label :first_name %>
<%= nc.text_field :first_name, :class => 'form-control', :value => #nc.first_name != nil ? #nc.first_name : '' %>
</div>
<div class='form-group'>
<%= nc.label :last_name %>
<%= nc.text_field :last_name, :class => 'form-control', :value => #nc.last_name != nil ? #nc.last_name : '' %>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12'>
<%= nc.submit 'Submit', class: 'btn btn-primary' %> <%= link_to 'Cancel', :back, class: 'btn btn-default' %>
</div>
</div>
</form>
</div>
<% end %>
When I actually run this and attempt to edit the model, before I can submit anything I get:
undefined method `model_path' for #<#<Class:0x00000003cb52c0>:0x007fb7022b18b0>
Did you mean? models_path
Change
redirect_to model_path
to
redirect_to #nc
If you run your rake routes, you'll see that model_path requires an id - using #nc tells rails to do what you want it to do.
Background: I would like to make a team and have the user verify the address of that team before the team is saved.
In my application I have a form that creates a team when the form is submitted. Within this form I have a partial that is suppose to render with a field location. When the user clicks submit within the partial form the location field (within the partial form and not the create team form) should go to the verify_Address action within the teams_controller. Instead of this happening I get an error when I load the page.
The error on pageload:
undefined local variable or method `verify_address' for #<#<Class:0x000001063ec8d8>:0x00000104555af0>
with this line highlighted: <%= form_for :team, url: verify_address, method: :post, remote:true do |f|%>
below are my files within the app.
route.rb file:
resources :users, :path => :captains, :as => :captains, :controller => "captains" do
resources :teams, :only => [:new, :create, :edit, :update, :destroy], controller: 'captains/teams'
end
resources :teams, :only => [:index, :show] do
resources :users, :path => :teammates, :as => :teammates, :controller => "teammates"
end
put 'captains/:id/teams/verify_address' => "teams#verify_address",as: 'verify_address'
get 'captains/:id/teams/verify_address' => "teams#verify_address"
controller/captains/teams_controller.rb:
class Captains::TeamsController < ApplicationController
respond_to :html, :js
def new
#team = Team.new
#captain = current_user
end
def verify_address
#address = params[:team][:location]
#validate_address = Team.validate_address(#address)
end
def create
#captain = current_user.id
#team = Team.create(
:name => params[:team][:name],
:location => params[:team][:location],
:sport => params[:team][:sport],
:captain_id => #captain,
:avatar => params[:team][:avatar]
)
if #team.present?
redirect_to #team # show view for team
end
binding.pry
end
end
the partial views/captains/teams/_verify_address.html.erb:
<%= form_for :team, url: verify_address, method: :post, remote:true do |f|%>
<div class = "form-group">
<%= f.label :location %>
<%= f.text_field :location, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.submit "Verify address" ,class: 'btn btn-success' ,id: 'verify_address' %>
</div>
<% end %>
the main form views/captains/teams/new.html.erb:
<%= form_for :team, url: captain_teams_path(#captain, #team), method: :post do |f|
%>
<div class="form-group">
<%= f.label :avatar %>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</div>
<div class = "form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.label :sport %>
<%= f.text_field :sport, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.label :location %>
<%= f.text_field :location, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.submit class: 'btn btn-success' ,id: 'team_role_submit' %>
</div>
<% end %>
</div>
<%= render partial: "/captains/teams/verify_address", locals: { address: #address, validate_address: #validate_address}%>
</div>
Creating a custom route verify_address generates verify_address_path url helper, which you should use in your form.
So I have a self-joining model defined. Basically a post on a forum, and a parent_post that it belongs to.
class Post < ActiveRecord::Base
has_many :replies, :class_name => "Post"
belongs_to :thread, :class_name => "Post", :foreign_key => "parent_post_id"
end
Which seems fundamentally sound. I created a new RESTful route for the reply action, and an action and view.
Routes:
resources :forums do
resources :posts do
member do
get 'reply'
end
end
end
The view layer and the control action seems to be where I'm getting hosed up.
def reply
#forum = Forum.find(params[:forum_id])
#post = #forum.posts.build
#post.thread = #forum.posts.find(params[:id])
#post.title = "RE: #{#post.thread.title}"
end
def create
#forum = Forum.find(params[:forum_id])
#post = #forum.posts.build(params[:post])
#post.user = current_user
if #post.save
redirect_to forum_post_path(#forum, #post), notice: 'Post was successfully created.'
else
render action: "new"
end
end
And in the view layer I was just trying to use the same scaffold generated form partial I'm using for the standard new and edit actions.
#reply.html.erb
<%= render :partial => 'form' %>
#_form.html.erb
<%= form_for [#forum,#post], :html => { :class => 'form-horizontal' } do |f| %>
<fieldset>
<legend><h1>New Thread</h1></legend>
<div class="control-group">
<%= f.label :title, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :title, :class => 'text_field span9' %>
</div>
</div>
<div class="control-group">
<%= f.label :body, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :body, :class => 'text_area span9' %>
</div>
</div>
<div class="form-actions">
<%= f.submit 'Submit', :class => 'btn btn-primary' %>
<%= link_to 'Cancel', forum_posts_path(#forum), :class => 'btn' %>
</div>
</fieldset>
<% end %>
However, the parent_post_id is getting lost when I'm creating the post and it's getting set to nil. Do I need to create another action? Is there some other way to set the thread? Some third thing?
This will work:
Reply action:
#forum = Forum.find(params[:forum_id])
#post = #forum.posts.build
#post.thread = #forum.posts.find(params[:id])
#post.title = "RE: #{#post.thread.title}"
Then add this to your view
<%= f.hidden_field :parent_post_id, #post.thread.id %>
BTW I question whether you need a custom reply method as opposed to using built-in RESTful methods but this should fix your problem and that wasn't really your question.
add
<%= hidden_field_tag :forum_id , #forum.id %>
to your form
So basically, when you're submitting to the Posts#create action you're submitting a url that looks something like this /forum/1/posts which removes the parent_post_id from the url. Since you're using that parent_post_id to build that url, you need a way to POST with it.
My suggestion is allowing a POST to a reply resource that is nested in the posts resource.
(ie POST /forums/1/posts/1/reply)
So maybe something like this
resources :forums do
resources :posts do
# :show is actually just pointing to a form
resource :reply, :only => [:show, :create],
:controller => 'reply' #otherwise gets routed to 'replies'
end
end
So you would also need a ReplyController but that would basically match your reply method on your post controller with a few changes.
def show
#forum = Forum.find(params[:forum_id])
#post = #forum.posts.find(params[:post_id])
#reply = #forum.posts.build
#reply.thread = #post
#reply.title = "RE: #{#post.thread.title}"
end
def create
#forum = Forum.find(params[:forum_id])
#post = #forum.posts.find(params[:post_id])
#reply = #forum.posts.build(params[:reply])
#reply.thread = #post
#reply.user = current_user
if #reply.save
redirect_to forum_post_path(#forum, #post), notice: 'Reply was successfully created.'
else
render action: "show"
end
end
The biggest problem would be that you would have to abstract your Post fields from your form for block. That's because the url you're trying to POST to is going to be different. But it shouldn't be too bad just doing something like this:
reply/show.html.erb
<%=
form_for #reply, :url => forum_post_reply_path(#forum, #post),
:html => { :class => 'form-horizontal' } do |builder|
%>
<fieldset>
<legend><h1>New Reply</h1></legend>
<%= render "posts/post_fields", :f => builder %>
<div class="form-actions">
<%= builder.submit 'Submit', :class => 'btn btn-primary' %>
<%= link_to 'Cancel', forum_post_path([#forum, #post]), :class => 'btn' %>
</div>
</fieldset>
<% end %>
posts/_form.html.erb
<%= form_for [#forum,#post], :html => { :class => 'form-horizontal' } do |builder| %>
<fieldset>
<legend><h1>New Thread</h1></legend>
<%= render "post_fields", :f => builder %>
<div class="form-actions">
<%= builder.submit 'Submit', :class => 'btn btn-primary' %>
<%= link_to 'Cancel', forum_posts_path(#forum), :class => 'btn' %>
</div>
</fieldset>
<% end %>
posts/_post_fields.html.erb
<div class="control-group">
<%= f.label :title, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :title, :class => 'text_field span9' %>
</div>
</div>
<div class="control-group">
<%= f.label :body, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :body, :class => 'text_area span9' %>
</div>
</div>
Note: There's probably a better way to declare the routes than I have, but I don't really know.