Understanding about render :partial in rails 3? - ruby-on-rails

When I change the content status on my application, background of database update works fine. But the link_to :loading operation is not working.
View : _feedback_question_status.html.erb for an element in page
<% if feedback_question.status == 1 %>
<span id="feedback_question">enabled -- <%= link_to "change", {:action=>"feedback_question_status",:status => 0,:feedback_question=>feedback_question.id}, :remote=>true, :loading => "$('#feedback_question_disable_#{feedback_question.id}').replaceWith('<p>Loading..</p>')", :update =>"feedback_question"%></span>
<% else %>
<span id="feedback_question">disabled -- <%= link_to "change",{:action=>"feedback_question_status",:status => 1, :feedback_question=>feedback_question.id }, :remote=>true, :loading => "$('#feedback_question_enable_#{feedback_question.id}').replaceWith('<p>Loading..</p>')", :update =>"feedback_question"%></span>
<% end %>
Controller:
has the update_attributes and render :partial=>'feedback_question_status'
And
on the Server:
Started GET "feedback/feedback_question_status?feedback_question=6&status=1" for 127.0.0.1 at 2012-08-27 16:25:47 +0530
... Snippet
(0.2ms) BEGIN
...
(30.7ms) COMMIT
Rendered _feedback_question_status.html.erb (2.7ms)
the last line shows the partial was renderd. but no changes on the views. It means there nothing happen to the element on the page.
rake routs for feedback_question:
feedback_feedback_question_status /feedback/feedback_question_status(.:format) feedback#feedback_question_status
feedback_questions feedback/new_feedback_question(.:format) feedback#new_feedback_question
edit_feedback_question /feedback/:id/edit_feedback_question(.:format) feedback#edit_feedback_question
update_feedback_question /update_feedback_question/:id(.:format) feedback#update_feedback_question
feedback_question_status /feedback_question_status(.:format) feedback#feedback_question_status
after refresh the page it shows the changes. but i don't want to load the page again.

You didn't passed the local variable "feedback_question" from controller to partial file _feedback_question_status.html.erb.
So you need to pass local variable "feedback_question" like below
render :partial => "feedback_question_status", :localts => { :feedback_question => #feedback_question }
where #feedback_question is a instance variable needs to be created in your controller.

Please replace this
<% if feedback_question.status == 1 %>
<span id="feedback_question">enabled -- <%= link_to "change", {:action=>"feedback_question_status",:status => 0,:feedback_question=>feedback_question.id}, :remote=>true, :loading => "$('#feedback_question_disable_#{feedback_question.id}').replaceWith('<p>Loading..</p>')", :update =>"feedback_question"%></span>
<% else %>
<span id="feedback_question">disabled -- <%= link_to "change",{:action=>"feedback_question_status",:status => 1, :feedback_question=>feedback_question.id }, :remote=>true, :loading => "$('#feedback_question_enable_#{feedback_question.id}').replaceWith('<p>Loading..</p>')", :update =>"feedback_question"%></span>
<% end %>
By this
<span id="feedback_question"><%= feedback_question.status == 1 ? "enabled" : "disabled" %> -- <%= link_to "change", {:action=>"feedback_question_status",:status => (feedback_question.status == 1 ? 0 : 1),:feedback_question=>feedback_question.id}, :remote=>true, :loading => "$('#feedback_question_disable_#{feedback_question.id}').replaceWith('<p>Loading..</p>')", :update =>"feedback_question"%></span>
Don't repeat your code.

Related

link_to with block in Rails

I have seen this code in this repository:
<%= link_to(:controller => 'account', :action => 'select', :account_id => account.customer_id) { account.customer_id.to_s } %>
(<%= account.login %> / <%= account.company_name %> )
This actually converts to the following HTML:
<a account_id="8282277272" action="select" controller="account">8282277272</a>
( loginname / companyname )
I am wondering how would you pass a block to link_to in order to make this work?
I think this is what you're looking for. The stuff inside the "do..end" will be put inside the a tag.
<%= link_to(:controller => 'account', :action => 'select', :account_id => account.customer_id) do %>
(<%= account.login %> / <%= account.company_name %> )
<% end %>
It should produce
<a href="<path to controller with account_id parameter>">
(username / Company, Inc.)
</a>
What was happening in your original code was that the expression { account.customer_id.to_s } was being passed as the block to link_to. If you want the customer id to be displayed along with the "login" and "company_name", put it inside the block.
<%= link_to(account_select_path(:account_id => account.customer_id.to_s)) do%>
<%= account.customer_id.to_s %>
<%end%>
(<%= account.login %> / <%= account.company_name %> )
and in your config/routes.rb, in the beginning of the file, add
match 'account/select' => "account#select", :as => :account_select

How to update my dropdown list without reloading the page

I've got a dropdown list where a user can select an option. The functionality works as it should but the page reloads each time. I've done a bunch of reading and seen examples but I'm having a hard time synthesizing the methods I've seen. I know I have to pass AJAX on a format.js call in the controller method like:
def update_device_position
...
if #cabinet.add_cabinet_item(#position_str,params[:position].to_i)
format.js
Then in the view, I have to add form_tag code like something like this:
<div id="add_device">
<%= form_tag(:url => {:action => url_for(:controller => "cabinets", :action => :update_device_position), :position => i , :id => #cabinet.id }, remote: true)%>
<td>
<%= select_tag :position_name, options_for_select(#selection_list) %>
</td>
<td>
<%= hidden_field_tag 'position', i %>
<%= submit_tag "Add" , :class => "btn" %>
</td>
</div>
When I select the new value for the cabinet slot and click submit, I get a routing error stating No route matches [POST] "/cabinets/99999999"
Thanks.

Rails 3: Can't add correct route to legacy code

Believe you can help me.
I'm trying to add new functionality to legacy code (Typo). But it seems that there is some problem about routing.
In the project routes are generated the following way:
%w{advanced cache categories comments content profiles feedback general pages
resources sidebar textfilters themes trackbacks users settings tags redirects seo post_types }.each do |i|
match "/admin/#{i}", :to => "admin/#{i}#index", :format => false
match "/admin/#{i}(/:action(/:id))", :to => "admin/#{i}", :action => nil, :id => nil, :format => false
end
My functionality is about merging articles. For that I've added new action in the /admin/content controller:
def merge
#some code here
end
A piece of a view partial (_form.html.erb) added by me:
<% if current_user.admin? and !#article.id.nil?%>
<div class=''>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %><%= text_field_tag :merge_with, nil, :size => 20 %>
<%= button_to 'Merge', admin_content_merge_path(:id => #article.id) %>
</div>
<%end%>
This partial is rendered by another partial (_edit.html.erb)
<%= form_tag(form_action, :id => "#{form_type}_form", :enctype => "multipart/form-data", :class => className) do %>
<%= render :partial => "form" %>
<% end %>
And finally _edit.html.erb is rendered by view new.html.erb
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
The problem is how to write a correct route for the controller action above which will allow me to render an edit page containing newly merged article. I wrote:
match "/admin/content/merge/:id" => "admin/content#merge",:as => 'admin/content/merge'
rake routes output:
admin_content_merge /admin/content/merge/:id(.:format) {:controller=>"admin/content", :action=>"merge"}
But the new or edit action is being invoked as I can see.
Apparently, my route is wrong, isn't it?
Could you please help me with this.
Thanks in advance!
Update
Up-to-date new.html.erb:
<% #page_heading = _('New article') %>
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
<% if current_user.admin? and !#article.id.nil?%>
<%= form_tag "/admin/content/merge/#{#article.id}" do %>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %>:
<%= text_field_tag :merge_with %><br />
<%= submit_tag "Merge" %>
<% end %>
<% end %>
Read the hint from the course:
HINT:Nesting is invalid in HTML.
That means that you can't nest form tags, don't put the form tag in another form tag, your nested form wont be able to do a correct action.
Since you have to put your code at the end of the page, try and see how to do it with having your merging form tag below the main edit article form tag. So basically you can find where the big form tag ends and put it below it.
Try to see if you can figure it out, and if not, don't hesitate to ask :)
Btw. I think everybody had some problem with this

Rails 3 - button_to update same page with controller#method

In my project I have the following form_tag to select a Site
<%= form_tag({:controller => "hvacs", :action => "index"}, :method => "get") do %>
<div class="field">
<%= select :p, :site_sel, #user_sites.map{|s| [s.name, s.id]} %>
</div>
<div class="actions">
<%= submit_tag("Select site") %>
</div>
<% end %>
This form_tag updates the index page through calling its method in the controller again.
I have the following button_to
<td><%= button_to 'Select', {:controller => "hvacs", :action => "select"}, :method => "get" %></td>
I would like to achieve a similar update with this as above rather than redirect to a new page with "select_path" etc, but the above does not seem to work.
How can I achieve this? Cheers!
OK, this looked so much like my AJAX problem, I tried to make it one!
I think all you need is a simple render statement in your select action
render :index
or
render :action => 'index'
But see http://guides.rubyonrails.org/layouts_and_rendering.html#using-redirect_to for more.
The following solution worked. Apologies if I was not so clear on what I was looking for.
<%= button_to 'Select', review_hvacs_path(:h => hvac, :a => params[:a], :s => params[:s]) %>
I was trying to pass parameters with the button, while staying on the review page.

variable / dynamic content is changing based on <div> -- why?

I have some unexpected behavior in a partial, which is rendered 9 times in users/show.html.erb. (Visit www.nowdoing.com/users/2 to see what I mean.) Here is the relevant part of the partial (it's verbose for debugging purposes):
<%= "object 1 = #{object.content}" %>
<div id="float_have" style="display:none;">
<%= "object 2 = #{object.content}" %>
<%= render :partial => 'nowposts/floatpost', :locals => { :object => object.content } %>
</div>
<%= "object 3 = #{object.content}" %>
Have! |
In box #1, :object => "#nowreading book"
In box #2, :object => "#nowlistening song"
Despite this, I'm seeing the following when I load my webpage:
object 1 = "#nowreading book"
object 2 = "#nowreading book"
object 3 = "#nowreading book"
That makes sense for box#1. But the following does NOT make sense for box#2:
object 1 = "#nowlistening song"
object 2 = "#nowreading book" *** this is wrong
object 3 = "#nowlistening song"
Can someone explain to me why including putting the "#{object.content}" within the facebox DIV causes the content to change? I find this behavior very peculiar. Your help is much appreciated!
--- EDIT ---
In users/show.html.erb:
<%= render :partial => 'nowposts/nowpost',
:locals => {:object => #nowreading,
:object_link => #reading_link,
:object_mode => "reading",
:doing_img => #reading_img,
:doing_url => #reading_url_text
} %>
<%= render :partial => 'nowposts/nowpost',
:locals => {:object => #nowlistening,
:object_link => #listening_link,
:object_mode => "listening",
:doing_img => #listening_img,
:doing_url => #listening_url_text
} %>
In nowposts/_nowpost.html.erb:
<div class ="status bl br">
Fresh on <%= object.updated_at.strftime("%b %d, %Y") %><br \>
<% if user_signed_in? %>
<%= "object 1 = #{object.content}" %>
<div id="float_have" style="display:none;">
<%= "object 2 = #{object.content}" %>
<%= render :partial => 'nowposts/floatpost', :locals => { :object => object.content } %>
</div>
<div id="float_wanna" style="display:none;">
<%= "object 3 = #{object.content}" %>
<%= render :partial => 'wishlists/floatpost', :locals => { :object => object.content } %>
</div>
Have! |
Wanna!
<% end %>
</div>
In application.html.erb:
<script type="text/javascript">
jQuery(document).ready(function($) {
$('a[rel*=facebox]').facebox({
loadingImage : '../images/loading.gif',
closeImage : '../images/closelabel.png'
})
})
</script>
The partial nowposts/_floatpoast.html.erb
<h2>Wanna!</h2>
<h3>You wanna do this? Great, put it on your bucket list. </h3>
<%= form_for(:wishlist, :as => #wishlist, :url => {:controller => "wishlists", :action => "create", :user_id => current_user } ) do |f| %>
<p><%= f.label :content %><br />
<%= f.text_field :content, :value => object, :size => "80" %></p>
<p><%= f.submit "Post!" %></p>
<% end %>
As mentioned in my comment below, this code was working in my last commit (a few days ago), before I implemented caching of an API result and these nested routes:
resources :users
resources :nowposts, :only => [:have_create, :create, :new, :show]
end
But I don't think that is the problem. I just ran another test, and object.content only changes when I have it inside this div:
<div id="float_have" style="display:none;">
I tried another random div:
<div id="status">
<%= "object 2 = #{object.content}" %>
</div>
and this displayed correctly. This makes me think that the problem is the Facebox script? But if so, I wonder why it worked a few days ago.
Let me know if you need anything else.
I don't understand your code at all, it is too ambiguous. 'object' is a pretty terrible name for a variable, and content is a really bad name for an attribute. Also, your locals for the partial are rendering here doesn't make much sense ({:object => object.content}????). If you would like help, please try to clarify what this means.
That being said, can you change each debug statement from
<%= "object 1 = #{object.content}" %>
to
<%= "object 1 = #{object.inspect}" %>
<%= "object 1 content = #{object.content.inspect}" %>
and display the results.

Resources