I am using nested fields in a form with fields_for..I need to add multiple attachments dynamically and submit the form. In the console I am getting params for attachment as
"reminder"=>{"message_addl_attachments_attributes"=>{"1380913359931"=>{"attachment"=>#<File:/tmp/RackMultipart20131005-4343-1cxemfz-0>}}
Iam not sure how to handle this in controller and save the attachment. I have built the associations properly.
In the controller I am doing like this.
def create_reminder
#reminder = Reminder.new
#addl = #reminder.message_addl_attachments.build(params[:reminder][:message_addl_attachments])
#addl.save
end
Please find the full params in console.
Processing ReminderPluginController#create_reminder (for 127.0.0.1 at 2013-10-05 00:53:33) [POST]
Parameters: {"reminder"=>{"subject"=>"nkljkl", "body"=>"<p>jkljkljkl jlkj</p>", "email"=>"", "message_addl_attachments_attributes"=>{"1380914609923"=>{"attachment"=>#<File:/tmp/RackMultipart20131005-4488-1agtr7m-0>}}}, "controller"=>"reminder_plugin", "select_batch"=>{"batch"=>"2"}, "select_department"=>{"department"=>""}, "recipients"=>"20", "authenticity_token"=>"L0py7Xdsf7JSQGqn2bdoE7EXDVN9ZmNNSwl0dbHMkfM=", "action"=>"create_reminder", "commit"=>"Send"}
[paperclip] Saving attachments.
Redirected to http://localhost:3000/reminder/create_reminder
Completed in 459ms (DB: 217) | 302 Found [http://localhost/reminder_plugin/create_reminder]
But it is not saving it in my rails public directory... In the db it is saving null values also.. Please help.
==============
myview.html.erb
<% form_for #reminder, :url => { :action => "create_reminder"
},:html=>{:multipart=>true} do |l| %>
<div class="addl_attachments">
<% l.fields_for :attachments do |a| %>
<%= render "message_addl_attachment_fields",:f=>a %>
<% end %>
<div class="add_addl_attachment">
<%= link_to_add_addl_attachment "#{image_tag
"buttons/add_2.png" } #{t('add_txt')}", l, :attachments %>
</div>
</div>
</div>
<div id="submit-button">
<%=submit_tag "#{t('send')}", :class => 'button',
:disable_with => "#{t('please_wait')}" %>
</div>
<% end %>
What your first have to check:
Is ImageMagick installed and working
Does your form have the attribute "multipart=>true"
Hope this helps :)
Related
I followed the Railscast for editing multiple records at the same time in one form. linked here: http://railscasts.com/episodes/165-edit-multiple-revised
This worked great for editing multiple onboarding_steps on the same form modal. Basically we mark the completion date of each step and hit save.
But now, one of these steps has a checklist of things to collect before it can be completed, and they want to put the checklist on the same form. And once I added in the <%= f.fields_for :onboarding_checkbox, onboarding_step.onboarding_checkbox do |checkboxes_form| %> section the form broke and threw a No route matches [POST] because the form is supposed to use PUT. For some reason adding in the nested attributes makes it want to do a POST instead of PUT.
This is it working properly before the nested attributes were added:
Started PUT "/onboarding_steps/update_multiple" for ::1 at 2018-06-15 15:25:25 -0500
Processing by OnboardingStepsController#update_multiple as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"",
"onboarding_steps"=>{"531"=>{"completed_date"=>""}, "280"=>{"completed_date"=>"02/09/2018"}}}, "commit"=>"Update"}
This is what it's doing with the nested section:
Invalid or incomplete POST params
Started POST "/onboarding_steps/update_multiple" for ::1 at 2018-06-15 15:47:08 -0500
ActionController::RoutingError (No route matches [POST] "/onboarding_steps/update_multiple"):
_edit_multiple.html.erb
<%= form_for :onboarding_steps, :url => update_multiple_onboarding_steps_path, :html => {:method => :put} do |form| %>
...
<% #onboarding_steps.each do |onboarding_step| %>
<%= fields_for "onboarding_steps[]", onboarding_step do |f| %>
... this is where it breaks the form ...
<% if onboarding_step.onboarding_checkbox.present? %>
<%= f.fields_for :onboarding_checkbox, onboarding_step.onboarding_checkbox do |checkboxes_form| %>
<%= submit_tag "Update", :class=>"btn btn-small btn-primary" %>
onboarding_steps_controller.rb
def edit_multiple
onboarding_step = OnboardingStep.find(params[:onboarding_step_id])
#onboarding_steps = OnboardingStep.includes(:onboarding_step_type).find(onboarding_step.group_steps.ids)
end
def update_multiple
logger.debug params
params.permit!
#onboarding_steps = OnboardingStep.update(params[:onboarding_steps].keys, params[:onboarding_steps].values)
#onboarding_steps.reject! { |s| s.errors.empty? }
if #onboarding_steps.empty?
redirect_to :back, notice: 'Update Successful'
else
render "edit_multiple"
end
end
which at the bottom does include onboarding_checkbox_attributes:[]
onboarding_step.rb has accepts_nested_attributes_for :onboarding_checkbox
routes.rb
resources :onboarding_steps do
resources :onboarding_checkboxes
member do
get "delete"
end
collection do
get :edit_multiple
put :update_multiple
end
end
Not sure where it's going wrong. It's Friday and my brain is fried
Had this same issue. Got around it by using each_with_index and assign an index to the record set:
In other words, instead of doing this:
<% #onboarding_steps.each do |onboarding_step| %>
<%= fields_for "onboarding_steps[]", onboarding_step do |f| %>
do this:
<% #onboarding_steps.each_with_index do |onboarding_step, index| %>
<%= fields_for "onboarding_steps[#{index}]", onboarding_step do |f| %>
Do not forget to include id in onboarding_checkbox_attributes:[]
This is my first question on here, so I am hoping I have not asked it incorrectly.
I have a generic new action on my tickets controller. Whenever I load tickets/new, it is creating a new item in the DB and committing it.
Here is the output from the server when the page is loading.
Started GET "/tickets/new" for ::1 at 2016-02-10 21:14:47 -0800
Processing by TicketsController#new as HTML
Customer Load (0.4ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`email` = 'tim#tim.com' LIMIT 1
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO `tickets` (`category`, `created_at`, `updated_at`) VALUES (3, '2016-02-11 05:14:47', '2016-02-11 05:14:47')
(6.4ms) COMMIT
Rendered tickets/_new_form.html.erb (23.3ms)
Rendered tickets/new.html.erb within layouts/application (48.4ms)
Rendered layouts/_user_nav.html.erb (0.8ms)
Rendered layouts/_navbar.html.erb (0.5ms)
Rendered layouts/_flashes.html.erb (0.5ms)
Rendered layouts/_minimal.html.erb (759.5ms)
Completed 200 OK in 893ms (Views: 822.1ms | ActiveRecord: 21.3ms)
This is the from the tickets controller.
def new
#ticket = Ticket.new
end
Here is the code for the form.
<%= form_for(#ticket, html: { class: 'form-horizontal' }) do |f| %>
<%= f.error_notification %>
<%= f.hidden_field(:category) %>
<%= f.hidden_field(:severity) %>
<br>
<%= f.form_group :summary do |f| %>
<%= f.label :summary, class: 'control-label col-md-2' %>
<div class='col-md-8'>
<%= f.text_field :summary, class: 'form-control' %>
<%= f.error_messages %>
</div>
<% end %>
<%= f.form_group :detail do |f| %>
<%= f.label :detail, class: 'control-label col-md-2' %>
<div class='col-md-8'>
<%= f.text_area :detail, class: 'form-control' %>
<%= f.error_messages %>
</div>
<% end %>
<br>
</div>
<div class="form-actions col-md-offset-2 col-md-10">
<%= f.submit 'Create', class: 'btn btn-primary' %>
<%= link_to "Cancel", tickets_path, class: 'btn' %>
</div>
<% end %>
Here are the relevant routes.
resources :tickets do
collection do
get :step_1
get :new_ticket
get :billing_new_1
get :internet_step_1
get :internet_step_2
get :internet_modem_reset
get :internet_step_1
get :internet_step_2
get :internet_create_1
get :internet_create_2
get :tv_step_1
get :tv_step_2
get :tv_step_3
get :tv_create_1
get :tv_create_2
get :tv_create_3
get :closed
get :sidenav
end
member do
put :close
end
resources :notes
resources :appointments
end
Help!!
--Tim
INSERT INTO `tickets` (`category`, `created_at`, `updated_at`) VALUES (3, '2016-02-11 05:14:47', '2016-02-11 05:14:47')
This is getting category (3) from somewhere, suggesting that there is some functionality somewhere which is saving the #ticket.
The simplest explanation I can see is that you have a before_action somewhere. It would benefit to show your entire TicketsController:
#app/controllers/tickets_controller.rb
class TicketsController < ApplicationController
before_action :set_user #-> something like this??
end
Since you're new, you can make your routes much more succinct (multiple resources):
#config/routes.rb
methods = %i(step_1 new_ticket billing_new_1 internet_step_1 internet_step_2 internet_modem_reset internet_create_1 internet_create_2 tv_step_1 tv_step_2 tv_step_3 tv_create_1 tv_create_2 tv_create_3 closed sidenav)
resources :tickets do
resources :notes, :appointments
collection do
methods.each {|method| get method }
end
put :close, on: :member
end
I ended up starting the whole ticket class over.
I think the error was in my html.
My guess is that the if statement with the bang was causing the ticket to save, because of an enum with that name on the model.
Here is what I think was the bad html.
<% if #ticket.category == :tv %>
Ok. Your tv is down, but your internet is still working.
<br>
Do you have any more details to add? If so, add them here. If not, just hit sumbit and we will open up a ticket with all of the information that you have provided us.
<% elsif #ticket.internet! %>
Ok. Your internet is down, but your tv is still working.
<br>
Do you have any more details to add? If so, add them here. If not, just hit sumbit and we will open up a ticket with all of the information that you have provided us.
<% elsif #ticket.billing %>
I am fresh out of questions.
<br>
Do you have any more details to add? If so, add them here. If not, just hit sumbit and we will open up a ticket with all of the information that you have provided us.
<% elsif #ticket.category == :internet_and_tv %>
Ok. Your cable and internet are both down.'%>
<br>
Do you have any more details to add? If so, add them here. If not, just hit sumbit and we will open up a ticket with all of the information that you have provided us.'%>
<% else #ticket.category == :plant %>
<%end%>
I had a form that I want user to answer every question, so I add a model-level validation.
I supposed if it pass validation, it should redirect to another page call "scenario" (I haven't finish it's view so it should show template missing). If it does not pass validation, it should render once again to the new page, remains the information already filled in, and show validation error.
But no matter I filled out those fields or not, when I click submit button, it always show me the index page instead of "new" or "scenario"(which should be template missing). It seems ignore what I have wrote in the action "create", and "create" is never been called.
I use rails c and insert a new record to test validation. It does work well, so I guess there is no problem for my model and validation.
I also try to make form_for redirect to "scenario" directly, to make sure it work well for form_for, and it does show templete missing to me, so there might be some problem for "create" itself. I really don't know what's going wrong.
<%= form_for #subject, :url => { :controller => 'appstores', :action => 'scenario' } do |f| %>
There is a similar question: rails form_for never invokes the create controller action to use redirect_to.
I had try to use "respond_with", not work. And also check my controller is named as appstroes_controller.rb with resources :appstores in routes.rb.
I use rails 4.2.4, ruby 2.0.0, and bootstrap 3, don't know whether the version cause those problem or not.
Any help would be appreciated, thanks!
app/controller/appstores_controller.rb
class AppstoresController < ApplicationController
def index
end
def new
#subject = Subjectinfo.new
end
def create
#subject = Subjectinfo.new(params[:subjectinfo])
if #subject.save
redirect_to :action => "scenario"
else # if not pass DB validation
render :action => :new
end
end
def scenario
end
end
app/view/appstores/new.html.erb
<%= form_for #subject, :url => { :controller => 'appstores', :action => 'create' } do |f| %>
<form class="form-horizontal">
<div class="form-group">
<%= f.label :username, "User Name:", :class=>"control-label", :for=>"username" %>
<% if #subject.errors[:username].presence %>
<span class="model-error"><%= #subject.errors[:username].join(", ") %></span>
<% end %>
<%= f.text_field :username, :autocomplete=>"off", :placeholder=>"User Name", :class=>"form-control", :id=>"username" %>
</div>
<div class="form-group">
<%= f.label :mobile_user, "Are you a mobile device user?", :class=>"control-label", :for=>"mobile_user" %>
<% if #subject.errors[:mobile_user].presence %>
<span class="model-error"><%= #subject.errors[:mobile_user].join(", ") %></span>
<% end %>
<div class="radio radio-primary">
<%= f.radio_button :mobile_user, "1", :id=>"mobile_user_1" %>
<%= f.label :mobile_user, "Yes", :class=>"control-label", :for=>"mobile_user_1" %>
</div>
<div class="radio radio-primary">
<%= f.radio_button :mobile_user, "0", :id=>"mobile_user_0" %>
<%= f.label :mobile_user, "No", :class=>"control-label", :for=>"mobile_user_0" %>
</div>
</div>
<div class="text-center">
<%= f.submit "NEXT", :class => "btn btn-default btn-outline btn-lg" %>
</div>
</form>
<% end %>
app/modle/subjectinfo.rb
(to support "attr_accessible" for rails 4, I had put "gem 'protected_attributes'" in my Gemfile)
class Subjectinfo < ActiveRecord::Base
validates_presence_of :username, :mobile_user
attr_accessible :username, :mobile_user
end
config/routes.rb
AppStore::Application.routes.draw do
match ':controller(/:action(/:id(.:format)))', :via => :all
root :to => "appstores#index"
resources :appstores
get "appstores/scenario"=>"appstores#scenario"
end
rake routes
Prefix Verb URI Pattern Controller#Action
/:controller(/:action(/:id(.:format))) :controller#:action
root GET / appstores#index
appstores GET /appstores(.:format) appstores#index
POST /appstores(.:format) appstores#create
new_appstore GET /appstores/new(.:format) appstores#new
edit_appstore GET /appstores/:id/edit(.:format) appstores#edit
appstore GET /appstores/:id(.:format) appstores#show
PATCH /appstores/:id(.:format) appstores#update
PUT /appstores/:id(.:format) appstores#update
DELETE /appstores/:id(.:format) appstores#destroy
appstores_rfscenario GET /appstores/rfscenario(.:format) appstores#rfscenario
Btw, here is what I saw form terminal, this is when I filled in all the fields.
Started POST "/appstores" for 127.0.0.1 at 2015-11-03 22:25:54 +0800
Processing by AppstoresController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7WV4Iw/0uHNSnuXpr8qa39oFEF9gZfKm8EyHGQna0o0=", "subjectinfo"=>{"username"=>"a1", "mobile_user"=>"1"}, "commit"=>"NEXT"}
Rendered appstores/index.html.erb within layouts/application (12.6ms)
Completed 200 OK in 91ms (Views: 88.0ms | ActiveRecord: 0.0ms)
Here is when I leave them blank, but no matter it is blank or not, it always render to index......
Started POST "/appstores" for 127.0.0.1 at 2015-11-03 22:25:54 +0800
Processing by AppstoresController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7WV4Iw/0uHNSnfuXpr8qa39oFEF9gZfKm8EyHGQna0o0=", "subjectinfo"=>{"esearch"=>""}, "commit"=>"NEXT"}
Rendered appstores/index.html.erb within layouts/application (12.6ms)
Completed 200 OK in 91ms (Views: 88.0ms | ActiveRecord: 0.0ms)
Remove the line match ':controller(/:action(/:id(.:format)))', :via => :all from your routes.rb file and never use it anymore. This pattern matches any route and it is on the first position, other routes in your file don't have a chance at all because of that.
I',m trying to achieve a simple nested model form in Rails 4. This is probably something very simple, but just can't figure it out.
So I have an edit view, in which I create the nested fields:
<%= f.fields_for :bankaccounts do |bankaccount| %>
<%= render 'bankaccount_fields', :f => bankaccount %>
<% end %>
These work fine and even the link:
<%= link_to_add_association 'add', f, :bankaccounts , :class => "link"%>
works fine. The fields appear as they should when clicked.
The real problem is, that when I submit the form. It doesn't send the parameters back to web server which have been inputted into these added fields. (Can't see them anywhere in the webrick console) The form only submits the old bankaccount parameters as it should:
"bankaccounts_attributes"=>{"0"=>{"iban"=>"121221", "swift"=>"121212", "id"=>"3"}, "1"=>{"iban"=>"33333", "swift"=>"33333", "id"=>"9"}, "2"=>{"iban"=>"121212", "swift"=>"211212", "id"=>"10"}
Above attributes should contain four bank accounts.
FWIW: Turbolinks is also disabled.
EDIT: Here's the code from bankaccount_fields partial:
<div id="tilit">
<div class="area-form">
<div class="col">
<div class="box-row">
<label for="iban" class="label">Iban</label>
<div class="input-row no-italic">
<%= f.text_field :iban, :id => "iban", :class => "input-text" %>
</div>
</div>
</div>
<div class="col">
<div class="box-row">
<label for="swift" class="label">Swift</label>
<div class="input-row no-italic">
<%= f.text_field :swift, :id => "swift", :class => "input-text" %>
</div>
</div>
</div>
</div>
pic of inspect element
EDIT: Debugger outputs reg. parameters:
(rdb:2) #_params
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"181xsndllcPmpvpMaDi70IXh8SpaSYxs0eiSo19qwfI=", "producer"=>{"name"=>"Anne", "RH_nro"=>"", "ytunnus"=>"", "prepaymentpercentage"=>"", "streetaddress"=>"", "zip"=>"", "city"=>"", "www"=>"", "bankaccounts_attributes"=>{"0"=>{"iban"=>"13123123", "swift"=>"121212", "id"=>"3"}, "1"=>{"iban"=>"33333", "swift"=>"33333", "id"=>"9"}, "2"=>{"iban"=>"121212", "swift"=>"211212", "id"=>"10"}}}, "commit"=>"TALLENNA", "action"=>"update", "controller"=>"producers", "id"=>"54"}
Should contain one more bankaccount_attributes record, but only contains the ones which are not dynamically added.
I've been scratching my head for hours now, so any help would be greatly appreciated.
Also sorry if the question is formed badly, this is my first :)
I have found the problem to my application, If don't know if anyone find this useful anymore or not.
I am guessing you have written your form_for inside a HTML table(that's what I did). If so the browser generates a inconsistent DOM. If you generate form inputs dynamically it wont put it inside the form unless you are selecting it through form selector. So the solution is put the form outside the HTML table.
What are your strong params & controller like?
They should be like this for nested attributes:
def params
params.require(:form_for_variable).permit(bankaccounts_attributes: [:iban, :swift])
end
Also, you'll need to include accepts_nested_attributes_for :bankaccounts in the model you're submitting the form to
I'm having a problem with Rails not POSTing anything in the params to an action.
I'm using a singular resource with a nested plural resource which may or may
not be where the problem is coming from (Rails has issues with form_for and singular
resource URLs).
Anyway, I have this in my routes:
resource :event do
resources :actions, :only => [:create], :controller => "events/actions"
end
The view:
<%= form_for([#event, Action.new], :remote => true) do |f| %>
<div class="field">
<%= f.label :team_id %>
<br />
<%= f.text_field :team_id %>
</div>
<div class="field">
<%= f.label :message %>
<br />
<%= f.text_field :message %>
</div>
<div class="field">
<%= f.label :score %>
<br />
<%= f.number_field :score %>
</div>
<br />
<%= f.submit "Update score" %> or <%= link_to "cancel", "#", :id => "cancel" %>
<% end %>
The create action:
def create
#event = Event.find(params[:event_id])
#action = #event.actions.create(params[:action])
end
Ok pretty standard no worries there.
But when I get the params from Rails nothing is there. :(
Params:
Started POST "/event/actions.4e67f09349ae71090c00000e"
Processing by Events::ActionsController#create as
Parameters: {"utf8"=>"Γ£ô", "authenticity_token"=>"stuff", "commit"=>"Update score"}
Completed 500 Internal Server Error in 31ms
What is going on here?
Edit:
If I remove the ":remote => true" line in my view,
I see that in my params I get one param ":format"
which appears to be the ID of the event.
However, I'm still not getting the action params. :(
Ideally I'd like to see those event & action models - I suspect that's where the problem lies. Without seeing those, a few suggestions:
Is 'accepts_nested_attributes_for :action' set in the event model?
Remove any 'attr_accessible' line from both models & see if things work. (Keep in mind you need to set accessible attributes for nested forms in the parent model)
'Action' seems like an imprudent name for a model. It's possible rails is overwriting 'action' methods with things related to the actual action
Hope this helps - I'd suggest posting the models if you still can't find a solution.