I made a Wysiwyg module where a user can create custom text areas for different sections of their website.
I do this by checking in the controllers if they have created one for this particular section yet. If they have, it redirects them :
def new
if Wysiwyg.find_by_name(params[:name]) != nil
redirect_to edit_admin_wysiwyg_path(Wysiwyg.find_by_name(params[:name]))
else
#wysiwyg = Wysiwyg.new(:name => params[:name])
end
end
The trouble is is Rails still believes its a 'new' even though I have redirected the user to edit. How can I 'clear' the controller's and make it really sincerely believe it is actually an 'edit' ?
Thanks!
Ah my problem was in my form instantiation
Old and Evil:
<% form_for(#wysiwyg, :url => admin_wysiwygs_path, :html => { :method => :post}) do |f| %>
Correct:
<% form_for #wysiwyg, :url => admin_wysiwyg_path do |f| %>
Related
I'm having a little trouble with using AJAX on something I've done before with no issues, but this site has a few different configurations which are causing trouble for me. The main problem I'm having, is when I click the Like link on a post, all of the like links on that page are changed to unlike, even though the one I clicked is the only one getting posted in the Database.
On my user's profile page (users/show.html.erb), I'm showing all of the posts (updates in this scenario) that the particular user has posted.
Here is my configuration thus far:
Users Controller, Show Action
def show
#updates = #user.updates.paginate(:page => params[:page], :per_page => 20)
end
Updates Controller, Like Action
def like
begin
#vote = current_user.vote_for(#update = Update.find(params[:id]))
if #vote.save
respond_with #update.user, :location => profile_path(#update.user)
end
rescue ActiveRecord::RecordInvalid
redirect_to #update
end
end
users/show.html.erb
<div class="like_button">
<%= render :partial => 'updates/like_button', :locals => {:update => update} %>
</div>
updates/_like_button.html.erb Partial
<% if current_user.voted_on?(update) %>
<%= link_to unlike_update_path(update), :method => :post, :remote => true do %>
<i class="ss-heart liked" title="Unlike Update"></i>
<% end %>
<% else %>
<%= link_to like_update_path(update), :method => :post, :remote => true do %>
<i class="ss-heart animate" title="Like Update"></i>
<% end %>
<% end %>
updates/like.js.coffee
$(".like_button").html("<%= escape_javascript render :partial => 'updates/like_button', :locals => {:update => #update} %>");
So just to refresh, the like button works and records the vote into the database, but it changes all of the like_buttons on the page to appear as if they have been liked instead of just the one post.
You need some way to distinguish your like buttons (by css class / id for example) and then you can alter them with jQuery concretely
$(".like_button").html("<%= escape_javas...
while currently $(".like_button") aims for all elements with that .like_button class (which are all).
I'm new to Ruby on Rails and I'm trying to update a device attribute (lastChangedBy) that will set its value to the user's IP address whenever the submit button is clicked. I wanted to do something like:
<%= form_for(#device) do |f| %>
.
.
.
<%= if click? ( f.submit "Commit Entries", class: "btn btn-primary" ) == true %>
<%= #device.lastChangedBy = request.remote_ip %>
<% end %>
but I don't think that's possible. I'm looking into using "button_to" but after searching online I am extremely confused to how to use it. I tried doing something like:
<%= button_to "Commit Entries", action: "setIp" %>
and then in DevicesController & in the helper.rb (because I wasn't sure where it would call the method) I made a simple method:
def setIp
Device.find(params[:id])
#device.lastChangedBy = request.remote_ip
end
but I am completely lost. Could someone please help me. It would be amazing if you were specific!
If you're already submitting a form, and want to set that parameter, do it in the controller:
class DevicesController < ApplicationController
def update
#device = Device.find(params[:id])
#device.last_changed_by = request.remote_ip # Tada!
if #device.update_attributes(params[:device])
redirect_to #device
else
render 'edit'
end
end
end
Tweak according to your application, but that's the basic idea.
Since you mentioned that you are unsure of how to utilize calling a function with button_to, and that you already have a method in your controller you can approach it as follows, by adding some fields to your view's button_to. With this approach you'll also be able to remove your form.
=button_to 'SetIp', {:controller => "your_controller",
:action => "setIp", :id => your_model.id}, {:method => :post }
And in your routes.rb
resources :your_controller do
post :setIp, :on => :collection
end
And in your_controller.rb
def setIp
device = Device.find(params[:id])
device.lastChangedBy = request.remote_ip
device.save!
#Can redirect to anywhere or render any page
redirect_to action: :index
end
I'm new to Rails, and I'm having an issue where I can't render a .js.erb file. I think the root of the issue is that Rails' internal routing mechanism expects me to name and configure my files just so, but I'm missing one or two pieces, and I'm not sure how to look for what needs to be fixed.
I have an HTML view with a link to a controller action:
<%# snip %>
<div id="holding_issues_list">
<%= link_to "Show issues on hold", {
:action => "show_user_issues",
:controller => "support",
:issue_type => "holding",
:user_id => #user.id },
:remote => true %>
</div>
<%# snip %>
I think (but I'm not sure) that :remote => true causes the link to make an AJAX call.
This is the corresponding controller action in the controller app/controllers/support_controller.rb:
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
end
I want this file, named show_user_issues.js.erb and placed in app/views/support, to be rendered when the controller exits:
$("#<%= #target_div %>").show();
alert('test');
$("#<%= #target_div %>").html(
"<%= escape_javascript render :partial => '_show_user_issues', :locals => {:target_div => #target_div, :issues => #issues} %>");
This is app/views/support/_show_user_issues.html.erb, the partial I want show_user_issues.js.erb to render:
<% for issue in #active_issues %>
<div id="issue_<%= issue.id %>_display">
<%= render :partial => 'show_issue_mini', :locals => {:issue => issue} %>
</div>
<% end %>
When I try clicking the link in my original HTML view, nothing happens. When I open it up in a new tab, I get this error message:
Template is missing
Missing template support/show_user_issues,
application/show_user_issues with {:locale=>[:en],
:handlers=>[:builder, :erb], :formats=>[:html]}. Searched in: *
"/home/<>/app/views" *
"/home/<>/gems/kaminari-0.14.1/app/views"
The alert('test') that I put into show_user_issues.js.erb doesn't show up, so I think that Rails is getting hung up on rendering that file - that is, the routing mechanism can't find it. How can I correct this issue?
P.S. I double-checked that I put in all the file names exactly as they are in the code base.
Change your controller action to handle the type of request.
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
respond_to do |format|
format.js
end
end
This will check the format of the request which is .js in case of :remote => true. So it will handle it by rendering the show_user_issues.js.erb file.
A couple other problems that I ran into after applying Manoj Monga's answer that I suspect other new Rails devs might run into:
In show_user_issues.js.erb, I had
[...].html("<%= escape_javascript render :partial => '_show_user_issues',[...]
The underscore before '_show_user_issues' caused the ERB builder to fail. It should have just been 'show_user_issues'.
In _show_user_issues.html.erb, I had
<% for issue in #active_issues %>
If you look closely at show_user_issues.js.erb, though, I named the variable #issues, not #active_issues:
[...]:locals => {:target_div => #target_div, :issues => #issues}[...]
So I changed the line in the HTML partial to
<% for issue in #issues %>
After these last couple changes, the new functionality I was adding worked as expected.
I created a new page on an existing controller.
I added 2 action methods on the controller: prompt_user and process_feedback.
So I get to the page via
redirect_to :controller => :users, :action => :prompt_user
And the form_for code looks like
<% form_for :user, #user do |f| %>
Which generates the following html
<form action="users/prompt_user" method="post">
Notice the action is prompt_user, where as I want to set it to process_feedback. I thought I could change the action with a button
<%= submit_tag "Process feedback" %>
But that didn't work.
So my question is how can I change the action to process_feedback?
Also, as you can probably tell, I'm very new to rails, so if I'm doing something especially obtuse, I'd love to find out what it is.
This is from memory, but I think you can do something like this:
form_for :user, #user, :url => { :action => :prompt_user } do |f|
Alternatively the same can be reached using form_tag with the syntax:
See my answer on this question: here https://stackoverflow.com/a/37145293/1248725
I decided to start a little project in rails 3 and I am a little bit stuck on a form... Where can I specified the f.submit action should go to a special controller / action ?
The code in the form is:
<%= form_for #user, :url => { :action => "login" } do |f| %>
<div class="field">
<%= f.text_field :email %><br />
<%= f.text_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
User is defined as #user = User.new in "index" method of "home_controller".
but I have the error:
No route matches {:controller=>"home", :action=>"login"}
as soon as I run http://0.0.0.0:3000
I am very sorry for this newbee question but I cannot find the routing details (I worked a little bit with rails a couple of years ago but...)
Thanks,
Luc
You don't need to specify any action for f.sumbit.
First of all, you need to make sure you put
resources :users
(for example)
in your routes.rb
then if you want to create a user
put
def new
#user = User.new
end
in your users_controller so you have a page to create new user
or you can put #user=User.new anywhere you like, remember to set
the route correctly
then
def create
#user = User.new(params[:id])
if #user.save
sign_in #user
redirect_to #user
else
render 'new'
end
end
is the part that does real work after you hit on submit
the actual part that connect your form with everything else is this line
<% form_for #user do |f| %>
you can change user to other object, and you can also edit form using update action in a controller.
Hope you got the idea
Whenever you use REST objects, the mere:
form_for #article
is enough for the form to find the proper path.
Otherwise, you can use helpers this way:
form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form")
More info here: http://edgeguides.rubyonrails.org/form_helpers.html