Rails:ArgumentError in MethodTypes#edit - ruby-on-rails

I tried to make an edit for ruby on rails, but it shows me the argument error about the edit. I am confused about this question.
Then, I have tried to put the different argument into index.html.erb However, it still does not work. For example m.id and m
This is index.html.erb
<% #methodtypes.each do|m| %>
<tr>
<td><%=m.name %></td>
<td><%=m.desp %></td>
</tr>
<%= link_to "Edit", edit_method_types_path(m.id) %>
<% end %>
<%= link_to "Create Method", new_method_types_path %>
This is my controller file:
class MethodTypesController < ApplicationController
def index
#methodtypes = MethodType.all
end
def show
#methodtype = MethodType.find_by_id(params[:id])
end
def create
#methodtype = MethodType.new(method_params)
#methodtype.save
if #methodtype.save
redirect_to method_types_path
else
render :new
end
end
def edit
#methodtype = MethodType.find_by_id(params[:id])
end
def new
#methodtype = MethodType.new
end
private
def method_params
params.require(:method_type).permit(:name, :desp)
end
This is my edit page which is edit.html.erb:
<%= form_for #methodtype do |f| %>
<div>
<%= f.label :name %>
<%= f.text_area :name %>
</div>
<div>
<%= f.label :desp %>
<%= f.text_field :desp %>
</div>
<%= f.submit %>
<% end %>
The result should show that I can edit my text. but, it shows the ArgumentError in MethodTypes#edit. Does someone can give me some suggestion, I do not know how to fix that.....

Wrong edit url path
It should be <%= link_to "Edit", edit_method_type_path(m.id) %> instead of <%= link_to "Edit", edit_method_types_path(m.id) %>
Also check your routes file It seems you are defining
resource: method_types
Change to
resources: method_types

<%= link_to "Edit", edit_method_types_path(m.id) %> should be <%= link_to "Edit", edit_method_type_path(m) %>, note that type is in singular.
Run rails routes -g method_type to confirm it.
Also, change the MethodType.find_by_id(params[:id]) to MethodType.find(params[:id]) in the controller.
Btw, you are calling save twice in your create method:
def create
#methodtype = MethodType.new(method_params)
#methodtype.save # delete this line
if #methodtype.save
redirect_to method_types_path
else
render :new
end
end

Related

How do i get the id of a model that i just created through form_with basically from one controller to another in Rails

Sort of new in rails so i might be doing things the wrong way
show.html.erb:
<% #feature.each do |p| %>
<br>
<h1><%= p.name %></h1>
<%= p.unit_price %>
<%= render partial: "shared/featureuse_form", locals: {feat_use: #feat_use , feature: p} %>
<%= button_to'Change' , feature_use_path(1) , :class => 'btn btn-primary' ,method: :delete %>
<% end %>
Right here in feature_use_path how do i get an id to pass it in order to make a delete button as i havent even created the model yet or its saved in its own controller should
_featureuse_form.html.erb:
<%= form_with model: feat_use do |f| %>
<%= f.number_field :total_units ,value: feature.max_unit_limit %>
<%= f.hidden_field :feature_id, value: feature.id %>
<%= f.hidden_field :usage_id, value: current_user.usage.id %>
<%= f.submit "confirm", id: "button"%>
<% end %>
Plans Controller
class PlansController < ApplicationController
before_action :authenticate_user!
def index
#plan = Plan.all
end
def show
#plan = Plan.find(params[:id])
#feature = #plan.features
#feat_use = FeatureUse.new
end
end
class FeatureUsesController < ApplicationController
def create
feature_use = FeatureUse.new(feature_use_params)
feature_use.total_units = params[:feature_use][:total_units]
feature_use.feature_id = params[:feature_use][:feature_id]
user = current_user.usage
feature_use.usage_id = user.id
feature_use.save
end
end
You're right that you can't create a button (method: :delete or otherwise) that relies on a record that doesn't yet exist.
Usually, a button like this would only be relevant to existing records anyway.
So, it's common to see an if statement like this:
<% if #feature_use.persisted? %>
<%= button_to 'Change' , feature_use_path(#feature_use.id) , :class => 'btn btn-primary', method: :delete %>
<% end %>
.persisted? returns false if the record is new and un-saved.

Creating multiple objects in a form Rails

So I have an interesting problem I'm working on. I am trying to create multiple objects of the same model in one view. I would like to display all the possible objects in my view, check boxes to select which ones to create, then submit and create all the corresponding objects.
Now the objects to select are gotten using an API request and returned in JSON format. The JSON is then displayed on the view for the user to select, then an array containing all the selected objects is sent back to the controller for creation.
Here is the relevant code that I've tried so far.
objects_controller.rb
def new
#possible_objects = <api call to get objs>
#objects = []
end
def create
params[:objects].each do |obj|
# create and save obj
end
end
objects/new.html.erb
<% form_for #objects do |f| %>
<% #possible_objects.each do |api_obj| %>
<%= check_box_tag(api_obj["name"])%>
<%= api_obj["name"] %>
<% end %>
<%= f.submit %>
<% end %>
This is definitely not the right approach, as the form will not accept an empty array as a parameter. I'm not sure where else to go with this, any pointers in the right direction would be great. Thanks.
Thanks to MrYoshiji for pointing me in the right direction, this is what ended up working
objects_controller.rb
def
#possible_objects = <api call to get objs>
end
def create
params[:objects].each do |object|
new_obj = Object_Model.new( <params> )
new_obj.save
if !new_obj.save
redirect_to <path>, alert: new_obj.errors.full_messages and return
end
end
redirect_to <path>, notice: 'Successfully created.'
end
objects/new.html.erb
<%= form_tag objects_path(method: :post) do %>
<% #possible_objects.each do |api_obj| %>
<%= check_box_tag 'objects[]', api_obj %>
<%= possible_object["name"] %>
<% end %>
<%= submit_tag 'Create'%>
<% end %>
Can you try the following?
# view
<% form_tag my_objects_path(method: :post) do |f| %>
<% #possible_objects.each do |api_obj| %>
<%= check_box_tag 'objects[names][]', api_obj["name"] %>
<%= api_obj["name"] %>
<% end %>
<%= f.submit %>
<% end %>
# controller
def create
params[:objects][:names].each do |obj_name|
YourModelForObject.create(name: obj_name)
end
end
See this comment on the documentation of check_box_tag: http://apidock.com/rails/ActionView/Helpers/FormTagHelper/check_box_tag#64-Pass-id-collections-with-check-box-tags

Repopulate form after error validation from another controller Rails 4.0

I am really embarrassed with this problem :
I want to post comments from one view and if errors occurs in form, i want the form to be repopulated. I use the render method but my form isn't repopulated.
I specify that the form is displayed from a view and use another controller action, by other words means :
Form called from : views/cars/show.html.erb code below :
<h1>Fiche détaillée</h1>
<%= #car.marque %><br>
<%= #car.modele %><br>
<%= #car.nbkm %><br>
<%= #car.couleur %><br>
<%= #car.disponibilite %><br>
<hr>
<% x=0 %>
<h1><%= pluralize(#car.comments.count, 'commentaire') %></h1>
<% #car.comments.each do |k| %>
<%= x+=1 %>
Email : <%= k.email %><br>
Sujet : <%= k.sujet %><br>
Commentaire : <%= k.commentaire %><br>
<%= link_to 'Supprimer', [k.car, k], method: :delete %><br><br>
<% end %>
<hr>
<h1>Ajouter votre commentaire</h1>
<div style='width:300px;'>
<% flash.each do |key, msg| %>
<% if msg.count >0 %>
<p class="bg-danger" style='padding:10px;'><%= pluralize(msg.count,'error') %>
<ul><% msg.full_messages.each do |m|%>
<li><%= m %></li>
<% end %>
</p>
<% end %>
<% end %>
</ul>
<%= form_for([#car,#car.comments.build]) do |co| %>
<%= co.label :'Email' %><br>
<%= co.text_field :email , class: 'form-control' %><br>
<br>
<%= co.label :'Sujet' %><br>
<%= co.text_field :sujet , class: 'form-control'%><br>
<br>
<%= co.label :'Commentaire' %><br>
<%= co.text_area :commentaire , class: 'form-control' %><br>
<br>
<%= co.submit :'Envoyer votre commentaire', class: 'btn btn-info'%>
<% end %>
</div>
below my controllers :
Controller 1 : controllers/cars_controller.rb
def create
#render text: params[:car].inspect
#car = Car.new(params[:car].permit(:marque,:modele,:nbkm,:couleur,:disponibilite))
if !#car.save
render 'new'
else
redirect_to #car
end
end
def show
#car = Car.find(params[:id])
end
def index
#cars=Car.all
end
Controller 2 : controllers/comments_controller.rb
class CommentsController < ApplicationController
def new
#comment=Comment.new
end
def create
#car = Car.find(params[:car_id])
#comment = #car.comments.create(params[:comment].permit(:email,:sujet,:commentaire))
if !#comment.save
flash[:error] = #comment.errors
flash.keep[:error]
render 'cars/show'
else
redirect_to car_path(#car)
end
end
def destroy
#car = Car.find(params[:car_id])
#comment = #car.comments.find(params[:id])
#comment.destroy
redirect_to car_path(#car)
end
end
I really don't understand why it does not work !!
Thank you so much for any assistance ;)
Edited:
I did some similar tests a bit for your case, the problem should due to the flash method.
Replace below lines:
flash[:error] = #comment.errors
flash.keep[:error]
render 'cars/show'
To:
flash.now[:error] = #comment.errors.full_messages
#car.reload
render 'cars/show'
Because flash[:error] will only be available in next action, means only works in redirect_to, so you have to use flash.now[:error] for rendering same view template. And most importantly, though the save failed of the #comment, the comment list in #car will still receive an instantiated invalid object return by the comment's create, build, or new method. It is because these three methods will always return instantiated object to the #car.comments collection, though it is failed to save it. So we must reload the #car object by #car.reload to refresh the memory and get correct Comment collection from the database.
Previous response:
In crate action, the create method #car.comments.create(..) will directly create and return an instantiated object without given attributes then try to save it if it passed the validation. If you have not set validations for Comment model, then it will directly save it. Try #car.comments.new(..) or #car.comments.build(..) for collection associations, it will not force to save an instantiated object after the validation passed. Also, check your Comment model for setting the validations.

Add id to url wont work

I have two model less views.
An index view:
<% #icd1.each do |f| %>
<%= link_to "#{f.von} #{f.bis} #{f.bezeichnung}", icd_show_path(f) %>
</p>
<% end %>
And an show view:
<% #icd1.each do |f| %>
<%= link_to "#{f.von} #{f.bis} #{f.bezeichnung}", icd_show_path(f) %>
</p>
<% f.icd2.each do |s| %>
<%= s.von %><%= s.bis %><%= s.bezeichnung %>
</p>
<% end %>
<% end %>
My controller:
class IcdController < ApplicationController
def index
#icd1 = Icd1.all
end
def show
#icd1 = Icd1.find(params[:id])
end
end
But somehow the link in the index view, wont work:
<%= link_to "#{f.von} #{f.bis} #{f.bezeichnung}", icd_show_path(f) %>
When i try to access the show page i get the error:
Couldn't find Icd1 without an ID
and the url only shows
http://localhost:3000/icd/show
without an id!
My routes:
get "icd/index"
get "icd/show"
1st: Very confusing naming: controller icd, model icd1..
2nd:
get "icd/show/:id", to: "icd#show", as: "icd_show"
or
get "icd/:id/show", to: "icd#show", as: "icd_show"
depends what url you want to get. It is confusing.
but I think this is what you need in your url;
<%= link_to "#{f.von} #{f.bis} #{f.bezeichnung}", icd_show_path(f) %>
and also the routes:
get "icd/:id", to: "icd#show", as: "icd_show"
after this next url will be available:
../icd/1 that will call action show from icd controller

simple_form_for not showing fields

I have a model (Project), in the 'new' action I have this code
<h1>Create new project</h1>
<% simple_form_for #project, :url => create_project_path do |project_form| %>
<%= project_form.error_messages %>
<ul>
<% project_form.input :name %>
<% project_form.input :subdomain %>
<% project_form.input :allow_email_report_client %>
<% project_form.input :allow_email_post_client %>
<% project_form.submit %>
</ul>
<% end%>
the controller code is simple
I have a load_and_authorize_resource (using CanCan) and the action code is this
def new
#project = Project.new
end
now, I do get a tag rendered but no fields inside this form
I have the exact same thing for Account model and there all of the fields are shown with no problem.
does anyone have an idea what is the problem?
Ah! You're missing the = signs in your fields:
<%= project_form.input :name %>
<%= project_form.input :subdomain %>
....
Without the =, the code within the <% %> will run, but there will be no output.
Also, good to know: in Rails 2.x you do not need the = for the form_for (Rails 3, however does need the =)
Make sure your new action looks like this:
def new
#project = Project.new
end

Resources