I have a form partial as follows:
_internet_service_form.html.erb
<%= simple_form_for #internet_service, remote: true do |f| %>
<%= f.input :start_date %>
<%= f.button :submit %>
<% end %>
When I render it in the new action of the controller, it returns a 500 internal server with no further explanation.
When I render it in the edit action of the controller, it renders correctly.
If I replace the partial with a text block with no rails tags in it, it renders correctly, so I know it's not a routing error.
new.js.erb
$("#result-content").html("<%= escape_javascript(render(partial: 'new')) %>");
new.html.erb
<%= render partial: 'internet_service_form' %>
internet_service_controller.rb
def new
#internet_service = InternetService.new
end
def edit
#internet_service = InternetService.find(params[:id])
end
These actions are being performed through AJAX, and the most useful logs I'm getting out of the development log are:
Started POST "/accounts/29/internet_services/new.js" for 10.12.68.100 at 2013-02-13 00:28:11 +1300
Processing by InternetServicesController#new as JS
... snip ...
Rendered internet_services/_internet_service_form.html.erb (14.9ms)
Rendered internet_services/_new.html.erb (24.3ms)
Rendered internet_services/new.js.erb (32.2ms)
Completed 500 Internal Server Error in 231ms
Related
I'd like to display an "Add to Favourites" button to users that are not logged in so that they can see that logged in users can add posts (in this case) to their favourites.
Here's the current code:
routes.rb
resources :users do
resources :favourites
end
resources :favourites, only: [:create, :destroy]
posts_helper.rb (I'll move this application_helper once I get it working)
PostsHelper
def new_favourite
if signed_in?
return current_user.favourites.build
else
return Favourite.new
end
end
end
show.html.erb
<%= render :partial => 'shared/favourites/favourite_form', :locals => { :object => #post } %>
_favourite_form.html.erb
<% if signed_in? && current_user.favourited?(object) %>
<%= render partial: 'shared/favourites/unfavourite', locals: { object: object } %>
<% else %>
<%= render partial: 'shared/favourites/favourite', locals: { object: object } %>
<% end %>
_favourite.html.erb
<%= form_for(new_favourite, remote: signed_in?) do |f| %>
<div>
<%= f.hidden_field :object_id, :value => object.id %>
<%= f.hidden_field :object_type, :value => object.class.name.demodulize %>
</div>
<%= button_tag(:type => 'submit', :id => 'add_favourite') do %>
Add to Favourites
<% end %>
<% end %>
I want it to not do an ajax call (ie submit the add favourite form using a page reload) if the user is not signed in so that it will see the user is trying to access a protected page, will redirect them to login and upon success [when it redirects them back to where they were originally trying to go] it will add the favourite.
Can someone advise what I would need to change to make this possible.
EDIT:
Code updated to reflect current state.
After signing in it redirects back to No route matches [GET] "/favourites" because favourites are a nested resource under users.
EDIT 2:
The redirect works pretty much the same as in Rails Tutorial:
Redirect user to sign in page (signed_in_user):
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-correct_user_before_filter
Store location to redirect user back to:
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-friendly_forwarding_code
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-friendly_session_create
The only difference is that on my signin page I use a facebook omniauth link for the user to login but the redirection after logging in still works as expected.
Use a helper method instead of current_user.favourites.build?
<%= form_for(new_favourite, remote: true) do |f| %>
Helper:
PostsHelper
def new_favourite
if signed_in?
return current_user.favourites.build
else
return Favourite.new
end
end
end
This is likely an error due to my minimal understanding of Rails and how to use variables across models, so if there is more code needed to answer it or if my terminology is incorrect, let me know and I will gladly update the question.
I have a feed of posts that I want a user to be able to "like." While the following code allows likes to work on an individual post's page - site.com:3000/posts/*post.id* - with the form data being passed of like[liked_post_id]:*post.id*, when I try to submit a like on a profile - site.com:3000/users/*user.id* - which contains a feed of posts, the form data being passed is like[liked_post_id]: (blank value)
How can I pass the post's ID within a feed of posts to the liked_post_id variable in _like.html.erb?
I have noticed that the action of the like form is /likes across the board. Would this will only work when you are on the page site.com:3000/posts/*post.id*? I'm curious if I need to modify the it so that the action of the form is /posts/*post.id*/likes when you are on the page site.com:3000/users/*user.id*
From my post view:
#views/posts/_post.html.erb:
...
<%= render 'posts/like_form' if signed_in? %>
...
Route to proper form:
#views/posts/_like_form.html.erb:
<div id="like_form">
<% if current_user.likes_this?(#post) %>
<%= render "posts/unlike" %>
<% else %>
<%= render "posts/like" %>
<% end %>
</div>
Like from:
#views/posts/_like.html.erb
<%= form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :liked_post_id, :value => #post.id %>
<%= f.submit "Like" %>
<% end %>
From profile (feed of posts):
#views/users/show.html.erb
...
<%= render #posts %>
...
Likes controller:
#controllers/likes_controller.rb
class LikesController < ApplicationController
before_filter :signed_in_user
def create
#post = Post.find(params[:like][:liked_post_id])
current_user.like!(#post)
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
end
...
User model:
#models/user.rb
...
def like!(post)
likes.create!(liked_post_id: post.id)
end
...
#frank-blizzard has pointed out that my form markup is an issue. On a post's page the generated markup is:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" value="73" />
While on the feed page:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" />
You can do something like this:
<% form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :post_id, :value => #post.id %>
<%= f.submit %>
<% end %>
The current_user.likes.build(...) part should get out of your view and inside your controller. You are using a current_user.like! method so I guess you have implemented already some method in user model to accomplish this. If not build your like in the create action of LikesController where you can access params[:like].
def create
#post = Post.find(params[:like][:post_id])
current_user.likes.build(#post)
# ...
end
EDiT
You might need to pass your #post variable correctly into your _like_form partials, like so:
#views/posts/_post.html.erb:
...
<% if signed_in? %>
<%= render 'posts/like_form', :post => #post %>
<% end %>
...
This will give you acceess to a post variable inside the partial so you can prepopulate your forms value with its id. See this questions as well Pass a variable into a partial, rails 3? and make sure to read up on how to pass variables correctly to partials. you can debug your views using <%= debug <variablename> %>
I'm using form_for to create a chatroom and when I view the page I get the following error:
NoMethodError in Chatrooms#new
undefined method `chatrooms_path' for #<#<Class:0xa862b94>:0xa5307f0>
Here's the code for the view, located in app/views/chatrooms/new.html.erb:
<div class="center">
<%= form_for(#chatroom) do |f| %>
<%=f.text_field :topic%>
<br>
<%=f.submit "Start a discussion", class: "btn btn-large btn-primary"%>
<% end %>
</div>
Here's the relevant controller:
class ChatroomsController < ApplicationController
def new
#chatroom = Chatroom.new
end
def show
#chatroom = Chatroom.find(params[:id])
end
end
If I change the line
<%= form_for(#chatroom) do |f| %>
to
<%= form_for(:chatroom) do |f| %>
it works fine.
I've searched around for similar questions but none of the solutions have worked for me. Help?
It is because you didn't create route/action for ChatroomsController. When you render new form it is pointing to create action by default, if you want to change handler action, use
form_for #chatroom, :url => some_other_path
I'm having trouble getting a view and controller to play nice together. I think I messed up my routing, any help would be great.
My controller looks like:
class AccountDetailsController < ApplicationController
def new
puts "in new"
end
def home
puts "in home"
end
end
My routes.rb looks like:
resources :account_details
My new.html.erb looks like:
<h1>AccountDetails#new</h1>
<%= form_tag(url_for(:controller => "account_details", :action => "new"), :method => "post") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Submit") %>
<% end %>
when I goto http://localhost:3000/account_details/new
I get my page and when I hit submit, I get this error:
Started POST "/account_details/new" for 0:0:0:0:0:0:0:1%0 at Wed May 02 22:38:10 -0400 2012
ActionController::RoutingError (No route matches [POST] "/account_details/new"):
Other than being clueless, what am I doing wrong? I thought my route would cover the [POST], no?
The proper method for creating new entry is PUT, not POST. You should remove :method => "post" from your template, so PUT method will be chosen automatically.
In Rails 3.0 I have the standard 'new' form that creates a new record, in this case a patient. It works fine and the validations / error showing also work fine.
The client now wants the form in Spanish.
So, I did this:
Created a new html doc called "newspanish" (Cut / paste code from "patients/new")
Created a new partial called "_form_newspanish" and referenced it where the "form" partial is in "newspanish" (Cut / paste code from view "patients/_form")
Created a controller action in "patients" called "newspanish" and cut/pasted exact code from the "new" action.
I left the "create" action untouched.
Added match "patients/newspanish" to routes.
Translated the english parts to spanish in views/newspanish and views/_form_newspanish. Just the stuff that users read on the page, of course...not the rails code.
And, it works, for perfect submissions.
For submissions that fail validation (like putting 3 digits in as a phone number), the page reverts to the view "patients/new" and shows the errors above the form... in English, of course, because patients/new is in English.
Of course, I want it to revert to "views/newspanish" and also show custom verbage in the validations errors (spanish).
Any thoughts on how I can get the patients/newspanish view to load when error validation it tripped?
Here's my code for "_form_newspanish"
<%= form_for(#patient) do |f| %>
<% if #patient.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#patient.errors.count, "error") %> prohibited this subscriber from being saved:</h2>
<ul>
<% #patient.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p><label for="mobile">Número de teléfono celular o móvil*</label>: <%= f.text_field :mobile %></p>
<br />
<%= f.submit "Inscribirme" %>
</div>
<% end %>
And controller... patients/newspanish
def newspanish
#patient = Patient.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #patient }
end
end
<%= form_for(#patient) do |f| %>
is creating a form whose url is submits to is "/patients" which matches to patients_controller, create action.
That create action probably has a line that says (in my pseudo code)
if #patient.save
redirect to somewhere
else
render :new
end
That line "render :new" is showing the "patients/new" view.
So what you have to figure out is to either
1) detect in patients_controller # create how to tell if its spanish, and render "newspanish"
OR
2) change <%= form_for(#patient) do |f| %> to submit to a new url that just handles the spanish version, and make a new controller or action that just handles the spanish form (and renders "newspanish" if the #patient doesn't save
For #2, you could manually change where the form submits to with
<%= form_for(#patient), :url => spanish_patients_path do |f| %>
and in your routes create
post "patients/spanish" => "patients#create_in_spanish"
and add def create_in_spanish to your patients controller