Rails 3.2
I have a view views/tickets/show.html.slim with a number of sections. I want to have different controllers for each section, and have actions like New Save Edit
So in my views/tickets/show.html.slim, I have:
- #customer_info = customer_info #ticket
h4.form-header Customer Information
.form-section.attachments
- if #customer_info.nil?
= render partial: 'tickets/sections/customer_info', locals: {ticket: #ticket }
In my view, I have:
= form_for CustomerInfo.new do |f|
- f.hidden_field :ticket_id, :value => ticket.id
.form-horizontal-column.customer-info
.form-group
= f.label :first
= f.text_field :first, maxlength: 50
.form-group
= f.label :last
= f.text_field :last, maxlength: 50
- logger.info("Marker 1")
.actions = link_to "Save", :controller => :customer_infos, :action => :create
- logger.info("Marker 2")
.clear
When I run the application in test mode, and I select a ticket, I get the following response:
Incomplete response received from application
In my test.log file, I have:
CustomerInfo Load (0.1ms)[0m SELECT customer_infos``.* FROMcustomer_infosWHEREcustomer_infos.ticket_id` = '1466026127' LIMIT 1
Marker 1
Rendered tickets/sections/_customer_info.html.slim (11.6ms)
Rendered admin/tickets/show.html.slim within layouts/application (563.0ms)
There is no Marker 2
If I replace:
.actions = link_to "Save", :controller => :customer_infos, :action => :create
With:
.actions = f.submit 'Save'
Then the form renders fine.
Any idea why this is not working?
Attempted fix:
In my tickets/section/_customer_info.html.slim, I did:
.actions = link_to "Save", create_customer_info_path, method: :post
In my routes.rb, I have:
post '/customer_infos/create' => 'customer_infos#create', as: 'create_customer_info'
I am now getting the following error message:
undefined method `customer_infos_path' for #<#<Class:0x00000008bb54d8>:0x00000009df3c30>
Where is customer_infos_path coming from?
If I do rake routes, I get:
create_customer_info POST /customer_infos/create(.:format) customer_infos#create
According to the Rails docs, using the controller option is frowned upon. You should set up your route with a name, like this:
post '/customers/create' => 'customer_infos#create', as: 'create_customer'
Then your view should look something like this:
.actions
= link_to "Save", create_customer_path, method: :post
Hope this helps!
Related
This is a complicated one so I will try to explain as best as I can. I have an attachment model and I am using carrierwave_direct as the gem. Carrierwave_direct requires uploading on one page and then the attributes on another page. The other page it needs to redirect you to is the edit page, however the attributes on the edit page I cannot validate through the model, unless I want the upload to fail(because it won't create an id with validations meant for another page.). I think what I am saying is how would I validate that model attributes have a presence only on the edit page and if the user exits the page without filling in the form, it deletes the model instance. I want it to do this because for my model to work they need it to create the model instance on upload. See my code in the controller below
def edit
#attachment = Attachment.find(params[:id])
end
def report_uploader
#uploader = Attachment.new.delivery
#uploader.success_action_redirect = uploaded_attachments_url
#uploader
end
helper_method :report_uploader
def after_upload
#attachment = Attachment.new(recruiter_id: current_user.id, uploader_name: current_user.first_name + " " + current_user.last_name)
#recruiter = current_user
#attachment.url = #attachment.delivery.direct_fog_url + params[:key]
#attachment.key = params[:key]
#attachment.filename = File.basename(#attachment.key)
#attachment.save
redirect_to edit_attachment_path(id: #attachment.id, :anchor => 'reports')
end
attachment modal
.head
%h2 Add Attachment
.close
%a{:href=>"#",:rel=>"modal:close"} ❎
.content
= direct_upload_form_for report_uploader , :html => { :class => "standard" } do |f|
.fieldgroup.upload
.field
.upload
= link_to "#", class: "btn primary" do
= image_tag 'loader-white.gif', alt: 'Loading', class: 'loading'
Upload Attachment
= f.file_field :delivery, class: 'file_upload', id: 'upload_attachment'
edit page(User is redirected here)
.content
%h2 Add Some Additional Stuff to your Attachment!
= form_for #attachment, html: {class: "standard manage-job"} do |f|
.fieldgroup.upload
.field
Your Attachment Title
%br
%a{href: attachment_path(id: #attachment.id), target: '_blank' }
= #attachment.filename
.field
%select{name: "attachment[attachment_type]"}
%option{value: ""} Select Attachment Type
%option{value: "Type A"} Type A
%option{value: "Type B"} Type B
%option{value: "Type C"} Type C
.field
Description of your Attachment
= f.text_area :description
.actions
= f.submit "Submit Report", class: "btn primary"
= link_to 'Cancel', attachments_path
I trying rewrite some data in model. Change_settings is GET-method, update_settings is POST. After click SUBMIT happens nothing. Data not change. Help me, please( what's wrong?
controller
def change_settings
#vacation_days = current_company.vacation_days
#illnes_days = current_company.illnes_days
end
def update_settings
current_company.update_attribute(:vacation_days, :illnes_days)
current_company.save
redirect_to account_company_path, notice: t('company.settings_changed')
end
change_settings view
.company_settings
= form_tag update_settings_company_path do
= field_set_tag do
= label_tag 'vacation_days'
= text_field_tag :vacation_days
= label_tag 'illnes_days'
= text_field_tag :illnes_days
%br
= submit_tag t('common.save'), class: 'btn'
= link_to t('common.back'), account_company_path, class: 'btn'
routes
resource :company, only: :all do
get :account
get :change_settings
post :update_settings
end
replace:
current_company.update_attribute(:vacation_days, :illnes_days)
current_company.save
with:
current_company.update_attributes(vacation_days: params[:vacation_days], illnes_days: params[:illnes_days] )
Basically you were not taken data sent from client into account
This bug has me perplexed.
I am displaying a Widget with the last 5 data points and a form for a new data_point. When I try to render both the form and the display partial it fails with a routing error. If I comment out either partial it works fine. So with only the form partial it works, or with only the display partial it works fine with the other.
Three relevant models/controllers: Widget, DataSet and DataPoint. DataPoints is STI so I have different partials to display the different types that match the class name.
When both render :partial => ... are uncommented it looks as if the data_point being passed to the second partial is the same as the data_point being passed to the first partial. It is all nil with only a data_set_id. I tried renaming the local from :data_point to :dp in case it was a name collision.
View, both partials and the routing error shown at the bottom.
Is there a limitation on passing :locals to partials when you are trying to render more than one partial in a view?
View: show.html.haml (the show action on the controller is empty)
- title "#{#widget.type.underscore.humanize} for #{#widget.data_set.name.to_s.downcase}"
.row
.span6
= render :partial => 'data_points/form', :locals => { :data_set => #widget.data_set, :data_point => #widget.data_set.data_points.build }
%br
- last_5 = #widget.data_set.data_points.last(5)
- if last_5.count > 0
%h3= "Last #{pluralize( last_5.count, 'Entry' )}"
- last_5.each do |dp|
%pre
= dp.inspect
= render :partial => "data_points/#{#widget.data_set.data_type.underscore}", :locals => { :data_set => #widget.data_set, :data_point => dp }
- else
%h3 No data yet!
= form_tag( push_widget_path #widget, :method => 'POST' ) do
= submit_tag( "Push Data", :class=>"btn btn-primary" )
= link_to "Edit your data", data_set_path( #widget.data_set ), :class=>'btn'
.span6
= image_tag "widgets/#{#widget.type.underscore}.png"
%p
Using the
%b= link_to #widget.data_set.name, #widget.data_set
data set.
= render :partial => "widgets/#{#widget[:type].underscore}", :locals => { :widget => #widget } rescue nil
%p
= link_to 'Edit', edit_widget_path(#widget), :class=>'btn'
Form Partial (data_points/_form.html.haml)
%pre
= data_set.inspect
%pre
= data_point.inspect
= form_for [data_set,data_point], :html=>{:class => 'well form-horizontal'} do |f|
-if data_point.errors.any?
#error_explanation
%h2= "#{pluralize(data_point.errors.count, "error")} prohibited this data_point from being saved:"
%ul
- data_point.errors.full_messages.each do |msg|
%li= msg
= render :partial => "data_points/#{data_set.data_type.underscore}_form", :locals => { :f => f, :data_point => data_point, :data_set => data_set }
= f.text_field :created_at, :type=>'datetime'
.form-actions
= f.submit 'Save'
Display Partial (data_points/_multi_value_data_point.html.haml)
.data-point{ :id=>"data-point-#{data_point.id}"}
%span.value
- data_point.data.map do |k,v|
- label = data_set.properties[:data_series][k][:name]
%span.key= "#{label}: "
= v
.meta
= data_point.created_at
%span.edit
= link_to 'Edit', edit_data_set_data_point_path( data_set, data_point )
%span.delete
= link_to 'Destroy', [data_set, data_point], :method => :delete, :data => {:confirm => 'Are you sure?'}
=# link_to 'Edit', '#', id: "edit-data-point-#{data_point.id}"
:javascript
$("#edit-data-point-#{data_point.id}").click( function(e) {
$("#data-point-#{data_point.id}").html( "#{escape_javascript( render :partial => "data_points/multi_value_data_point_form", :locals => { data_set: data_set, data_point: data_point } )}");
return false;
});
Routing Error
Routing Error
No route matches {:action=>"edit", :controller=>"data_points", :data_set_id=>#<MultiValueDataSet id: 4, ... properties removed ... type: "MultiValueDataSet">, :id=>#<DataPoint id: nil, data: {}, data_set_id: 4, created_at: nil, updated_at: nil>}
Try running rake routes for more information on available routes.
The problem stems from the fact that the form is building a new element that isn't saved, and last is returning that unsaved element.
Simple solution, replace .last(5) with .find( :all, order: 'id desc', limit: 5 )
UPDATE
I have mange to get it working by changing the Model call from
#comments = VideoComment.all(:conditions => { :video_id => #video.id}, :limit => 5, :order => :created_at)
#comments = VideoComment.last(5).reverse
It works, but it gives me the last video comments from all the videos whereas I only want those from the current video (#video.id).
Any clue on how to do that?
I have a Videocontroller and a VideoComments controller which manages the comments for the Video controller. I am trying to make my remote form update the comments list with ajax but it does not seem to work. Can you find what I did wrong?
HTML code of the show page :
- if current_user
#comment-form
= render 'video_comments/comment_form'
%ul
#comments
= render #comments
video_comments/_comment_form.html.haml
= form_for current_user.video_comments.build(:video_id => params[:id]), :remote => true do |f|
.form-fields
.comment-content
= f.text_area :content, rows:2
= f.hidden_field :video_id
= f.hidden_field :user_id
.submit-form
= f.submit "Add a comment", :class => "btn btn-default "
The Video_Commentscontroller createaction :
def create
#comment = VideoComment.create(params[:video_comment])
#video = #comment.video
#comments = VideoComment.all(:conditions => { :video_id => #video.id}, :limit => 5, :order => :created_at)
render :toggle
end
The toggle.js.erb file which manages the page changes :
$("#comment-form").html("<%= escape_javascript render 'comment_form' %>");
$("#comments").html("<%= escape_javascript render #comments %>");
If you are using Rails 3 you can do
#comments = VideoComment.where(:video_id => #video.id).order(:created_at).limit(5)
Or if you have relations properly defined you can also do
#comments = #video.comments.order(:created_at).limit(5)
I am trying to create a generic set of Submit, Cancel, and Destroy actions for forms. At this point, it appears that everything is working, except that I lose :back functionality then a form reloads due to validation errors. Is there a way to catch the fact that validation has failed, and in that case, keep the request.env['HTTP_REFERER'] or :back value the same without having to edit every controller?
= simple_form_for #announcement do |f|
= f.error_notification
= f.input :message
= f.input :starts_at
= f.input :ends_at
#submit
= f.button :submit
= "or "
= link_to("cancel", url_for(:back))
.right
- if !f.object.new_record?
- resource = (f.object.class.name).downcase
= link_to "destroy", url_for(:action => 'destroy'), :confirm => "Are you sure that you want to delete this #{resource}?", :method => :delete
.clear
.non_input
#post_back_msg
#indicator.inline
= image_tag "indicator.gif"
.inline
= "Please wait..."
.non_input
How about something like a helper method with something like this?
#previous = #previous.blank? ? request.env['HTTP_REFERRER'] : #previous
Then the Cancel button is just:
link_to('Cancel', #previous)
Does this work?
link_to "Cancel", #model.errors.any? ? request.env['HTTP_REFERRER'] : :back