This one has been bugging me for a while. Hoping someone can help...
I have an ajax request as follows (this one works perfectly).
Controller:
def destroy
#property = Property.find(params[:property_id])
#property_asset = #property.property_assets.find(params[:id])
#property_asset.destroy
property = Property.find(params[:property_id])
#images = property.property_assets.asset_content_type_starts_with('image')
#videos = property.property_assets.asset_content_type_starts_with('video')
#docs = property.property_assets.asset_content_type_starts_with('application')
respond_to do |format|
format.html
format.js
flash[:notice] = "Deleted"
end
end
Destroy.js.haml:
$("#images").html("#{escape_javascript(render 'images')}");
$("#videos").html("#{escape_javascript(render 'videos')}");
$("#docs").html("#{escape_javascript(render 'docs')}");
This method, when called renders the partials on the page without needing to do refresh. Exactly what I want.
On the same page I have a file upload that calls a Create method:
def create
#property = Property.find(params[:property_id])
#property_asset = #property.property_assets.create
property = Property.find(params[:property_id])
#images = property.property_assets.asset_content_type_starts_with('image')
#videos = property.property_assets.asset_content_type_starts_with('video')
#docs = property.property_assets.asset_content_type_starts_with('application')
if #property_asset.save
if #property_asset.update(property_asset_params)
respond_to do |format|
format.html
format.js
flash[:notice] = "File added"
end
end
end
end
_create.js.haml is the same as the destroy file above but does not work with the any of the renders. So if I was to just try
$("#images").html("#{escape_javascript(render 'images')}");
The create method takes me to create.js.haml fine, I know if this because I can just enter a console.log and it spits out fine, but adding the line above and the console.log line fails and it doesnt render.
The images partial is:
- #images.each do |asset|
= form_for [#property, asset], remote: true do |f|
- if asset.id.present?
.row
.large-2.columns
%ul.clearing-thumbs{"data-clearing" => ""}
%li
%a{href: asset.asset.url}
%img{src: asset.asset(:thumb)}
.large-10.columns
.row
.large-12.columns
= f.text_field :description, :placeholder => 'Description', :id => 'test1'
.row
.large-8.columns
%p
= f.check_box :private, :id => 'private'
%label{for: "private"} Private
.large-2.columns
= f.submit 'Update', :class => 'button tiny right round', :disabled => '', :html => { :id => "update#{asset.id}" }, :remote => true
.large-2.columns
%p.right
= link_to 'Delete', [#property, asset], method: :delete, :class => 'button tiny right round alert', :remote => true
Let me know if I need to clarify anything. thanks.
Logs
This is when I just add in a simple console.log. JS console outputs fine. All ok.
(18.8ms) commit transaction
Rendered property_assets/create.js.haml (1.9ms)
Completed 200 OK in 4474ms (Views: 13.4ms | ActiveRecord: 169.5ms)
This is when I add
$("#images").html("#{escape_javascript(render 'images')}");
When the render is added log is:
Rendered property_assets/_images.html.haml (19.0ms)
Rendered property_assets/create.js.haml (23.6ms)
Completed 200 OK in 4017ms (Views: 34.7ms | ActiveRecord: 54.1ms)
The log before that is all the same, I'm adding a file into PropertyAsset using paperclip and I have papertrail tracking versions. When the render fails I need to refresh the page in order for the image to appear in the list.
Related
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!
Rails 3.2
jQuery-Rails
I've searched all over and I've only found js ways to update a partial or add a partial via JS. I've had no luck with this one. Here is the issue:
I have a list of referrals on a page, the referrals are posted on the index page as partials. The referral box has a reply button and a count of how many replies per referral. Statically I had it working but I'm getting no luck with updating the referral box with the new count and replacing the reply button with an icon. The is getting to the database but I'm screwing something up with the refresh of the box. Help please!
Do I use locals to render the new variables?
Should I remove my if statements from the partial and just use the js.erb file to determine what to show?
Reply controller:
class RepliesController < ApplicationController
respond_to :html, :js
def new
#referral = Referral.find(params[:referral_id])
#reply = #referral.replies.new(:user_id => params[:user_id], :referral_id => params[:referral_id])
if #reply.save
format.html { notice: 'Replied' }
respond_with(#referral, :location => referrals_path)
end
end
end
_referral partial:
.referralBox.cornerShadow{:id => "Referral#{referral.id}"}
- if current_user == referral.user or current_user.role == 'administrator'
= link_to '<i class="icon-pencil icon-large icon-grey" rel="tooltip" title="Edit"></i>'.html_safe, edit_referral_path(referral), class: "referralEdit"
= link_to '<i class="icon-remove icon-large icon-grey" rel="tooltip" title="Delete"></i>'.html_safe, referral, method: :delete, data: { confirm: 'Are you sure?' }, class: "referralClose"
.referralProfile
= link_to "#{image_tag(referral.user.image.url, :class => "img-circle img-border border-white", :style => "thumb")}".html_safe, referral.user
%ul.unstyled.inline
%li
= referral.description
- unless referral.replies.count == 0
- if referral.user == current_user
%i.icon-comments.icon-large{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- else
%i.icon-comments.icon-large.orange{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- unless current_user == referral.user
- if referral.replies.any?
%i.icon-ok.icon-large.pull-right.orange{"rel" => "tooltip", "title" => "Replied"}
- else
= link_to '<i class="icon-ok icon-large pull-right icon-grey" rel="tooltip" title="Reply"> Reply</i>'.html_safe, new_referral_reply_path(:referral_id => referral.id, :user_id => current_user.id), :id => "ReplySubmit", :remote => true
new.js.erb view
$(".referralBox").html("<%= j(render(:partial => "#referral")) %>");
application.js
jQuery.ajaxSetup({
'beforeSend': function (xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});
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 want to save the id of the wishlist in a wishlist_entry table in a column like wishlist_id.
I have an link_to element like this:
<%= link_to 'Create', new_wishlist_entry_path(:wishlist => #wishlist.id) %>
This gives me the following url:
http://localhost:3000/wishlist_entries/new?wishlist=36
The wishlist_entry_controller's new action is:
def new
#wishlist_entry = WishlistEntry.new
#wishlist = Wishlist.find(params[:wishlist])
respond_to do |format|
format.html # new.html.erb
format.json { render json: #wishlist_entry }
end
end
The create action is:
def create
#wishlist_entry = WishlistEntry.new(
:wishlist_id => Wishlist.find(params[:id]),
:entry_name => params[:wishlist_entry][:entry_name],
:description => params[wishlist_entry][:description]
)
I get this error:
Couldn't find Wishlist without an ID
app/controllers/wishlist_entries_controller.rb:44:in `create'
The error is in the link:
:wishlist_id => Wishlist.find(params[:id]),
Whats wrong? How can I save the id of the new wishlist in the field wishlist_id of wishlist_entry?
I think the problem is that the wishlist id is coming in params[:wishlist] not params[:id]. The error you are seeing in your controller is because params[:id] is nil and the Wishlist class doesn't know what to do with Wishlist.find(nil).
Try this:
def create
#wishlist_entry = WishlistEntry.new(
:wishlist_id => params[:wishlist]),
:entry_name => params[:wishlist_entry][:entry_name],
:description => params[wishlist_entry][:description]
)
Without knowing exactly what you're trying to do here, it looks like the problem is that wishlist_id isn't getting passed to your create action.
The best way to fix this is to take advantage of the nested resources you've already set up by changing
<%= link_to 'Create', new_wishlist_entry_path(:wishlist => #wishlist.id) %>
to
<%= link_to 'Create', new_wishlist_wishlist_entry_path(:wishlist => #wishlist.id) %>
(wishlist_wishlist_entry looks pretty bad, but you can change it by using :as => 'whatever' in your routes)
Then in your new action:
#wishlist = Wishlist.find(params[:wishlist_id])
In your form:
form_for([#wishlist, #wishlist_entry])
And in your create action:
#wishlist = Wishlist.find(params[:wishlist_id])
#wishlist_entry = #wishlist.wishlist_entries.build(params[:wishlist_entry])
I have a form:
<%= form_for(:report_main, :url => {:action => 'exporttoxiccreate'}) do |f| %>
<%= collection_select(:waste, :code, Waste.find_all_by_istoxic(false), :id, :code, :include_blank => '') %>
<%= f.check_box(:q_pripadnost) %>
<%= f.text_field(:amount) %>
<% end %>
and this code in controller:
def exporttoxiccreate
#report = ReportMain.new
#reportexport = ReportExport.new
#reportparam = params[:report_main]
#report.waste_id = #reportparam.waste.code
#report.amount = #reportparam.amount
if #report.save
#reportexport.report_main_id = #report.id
else
redirect_to(:action => 'exporttoxicnew')
end
#reportexport.q_pripadnost = #reportparam.q_pripadnost
if #reportexport.save
redirect_to(:action => 'show', :id => #reportexport.id)
else
redirect_to(:action => 'exporttoxicnew')
end
end
I want to save in two tables, in two objects data from this form, and I need to separate params to manipulate with. I tried with this:
#reportexport.q_pripadnost = #reportparam.q_pripadnost
I want to set q_pripadnost field in #reportexport with some value from param.
Where I make mistake?
When you get params from a form in Rails, it comes in the form of a hash. For example:
params[:report_main][:waste]
params[:report_main][:amount]
So when you call #reportparam = params[:report_main], you are setting #reportparam to a hash, but then you are trying to use it later like an object. For example, instead of #reportparam.q_pripadnost, use #reportparam[:q_pripadnost].
You can take a closer look at your variable by temporarily changing your action to show a text version of the variable, for example:
def exporttoxiccreate
#reportparam = params[:report_main]
render :text => #reportparam.to_yaml
end