remote_form_for doesn't call rjs template - ruby-on-rails

So here is my form
<% remote_form_for([:admin, Page.new]) do |f| %>
<ol>
<li>
<%= f.label(:title) %>
<%= f.text_field(:title) %>
</li>
<li>
<%= f.label(:parent_page) %>
<%= f.select(:parent_page_id, Page.roots.map { |p| [p.title, p.id] }.unshift(["none", nil])) %>
</li>
</ol>
<div class="modal-controls">
<%= submit_tag("Save") %> or <%= link_to_function("cancel", "R.Pages.hideAdd();") %>
</div>
<% end %>
And my action
def create
#page = Page.create(params[:page])
#languages = Language.all
#languages.each do |language|
#page.page_languages.create(:language_id => language.id)
end
For some reason the submitted for does not call the create.js.rjs template, but instead tries to call create.html.erb, do i need some sort of extra setting with the form?
btw i am using rails 2.3.5

I can't remember the exact default behavior in rails, but have you tried putting a respond_to at the end of your controller action:
respond_to(:html, :js)
Hope this helps.
EDIT
I went back to check on the default behavior for Rails in respect to rendering views. Rails favors convention over configuration in this instance. The default behavior is that Rails automatically renders views with names that correspond to actions. You don't need the respond_to any more if you stick to this convention. Here is the documentation.
Just wanted to update my post with the correct info... glad you figured your problem out.

I had named my template create.rjs.js instead of create.js.rjs, thats why i didnt work

Related

Why does Ruby on Rails keep telling me about an uninstantiated variable?

EDIT: SOLVED, view the solution in Brian Kunzig's answer+comments.
I've decided to try out Ruby on Rails and have been constantly running into this problem. I was searching around for problems like this but none of the solutions have done the trick for me. It seems that I constantly write a part of code that just isn't correct. So here are some code snippets:
(ignore what the code would be for, it's just to try stuff out)
My controller:
class AuthsController < ApplicationController
def index
#auths=Auth.all
end
def new
#auth=Auth.new
end
def show
#auth=Auth.find(params[:id])
end
end
My index.html.erb:
<div style="margin: 0 auto; width:50%; text-align: center">
<h1>Please authorise your use of this webpage and its database(s).</h1>
<%= form_for :auth, url: auths_path do |f| %>
<% if #auth.errors.any? %> ==> RAILS REPORTS ERROR IN CODE HERE
<div id="error_explanation">
<h2>
<%= pluralize(#auth.errors.count, "error") %> prohibited
this authentification from being saved:
</h2>
<ul>
<% #auth.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :username %><br>
<%= f.text_field :username %>
</p>
<p>
<%= f.label :password %><br>
<%= f.text_field :password %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
</div>
So, bottom line. Rails is saying that I cannot use #auth in the form_for block, for example. Or anywhere else for that matter.. It always says that it belongs to NilClass or something like that. It obviously wants me to instantiate it somehow, but isn't it enough to make the method new and put in the line: #auth=Auth.new ?
I'm just confused with this situation because I can't figure out how it's supposed to go. Thanks a lot !
P.S. I'm using <%= form_for :auth, url: auths_path do |f| %> because it won't accept #auth, that's what the error in the next line is. I have seen solutions to instantiate it "on the go" outside of the controller but I want to do it the way it's supposed to be done.
You should be putting this form in the new.html.erb file and not the index. The index is for listing entries while the new and create actions handle POST requests. You're getting an error because you're trying to list all Auth's when none have been created. Also, you're sending a form via a GET request if you're using standard rails routing. Use resourceful routing and put this form in your new view for that controller and it should work.
Routes file should be:
resources :auths
This will provide all the necessary routing automagically. If you type rake routes after modifying this you will see the newly generated urls and the helpers to them. You will notice it affords the create and update actions a POST/PUT request while others are GET.

Default path to look for partial

In my app/views/conversations/index.html.erb, I am writing:
<%= render #conversations %>
hoping that it would find a partial named _conversation.html.erb inside the same directory, and use it to render each elements in #conversations. (The usual Rails way)
But I get a missing template error: Missing partial mailboxer/conversations/_conversation.
I am using a Mailboxer gem, and there were no documentations for this. I know I could render a partial explicitly by <%= render partial: 'conversation', locals: { conversations: #conversations } %>.
Yet still, I would like to know why my app is looking for a partial for #conversations in mailboxer/conversations/, not conversations/, and if there is a way to change this behavior.
More information
<% #conversations.each do |conversation| %>
<%= div_for conversation %>
<% end %>
produces HTML:
<div class="mailboxer_conversation" id="mailboxer_conversation_16"> ... </div>
<div class="mailboxer_conversation" id="mailboxer_conversation_17"> ... </div>
....
Perhaps the mailboxer_ in front of conversation has something to do with this situation also?
This happens because, in later versions of Mailboxer, models are namespaced under Mailboxer. (e.g. Mailboxer::Conversation, Mailboxer::Message.)
I commented on the GitHub issue also.
You could try providing the full path to the partial, e.g.
<%= render :partial => "yourfoldername/conversation", collection: #conversations %>

Moving rails from to from _form.html.erb to application.html.erb

I have most of the functionality done for a site. Now I am trying to make it look nice. I have a _form.html.erb that works great.
<%= form_for(#card) do |f| %>
<% if #card.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#card.errors.count, "error") %> prohibited this card from being saved:</h2>
<ul>
<% #card.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :event %><br />
<%= f.text_field :event %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Files
view
- cards
-- new.html.erb
-- index.html.erb
-- show.html.erb
- layouts
-- application.html.erb
- pages
-- index.html.erb
I make a call for the form from new.html.erb and it works sends it to show.html.erb, just as I want. I'm using bootstrap and decided to make use of the nav bar. I have placed the nav bar code into the application.html.erb. It works just fine, well kind of. I want what would normally be a search function to be the add a new card.
When I add the form call it does not work, when I add it directly to the application page it does not work. I'm not sure, I have spent hours on this. I got it to work only on the show.html.erb page, both index pages would error out. I honestly don't remember how I did this though.
I'm trying to learn by doing, but I am stuck and need some help.
Thank you,
Ian
I guess that when you say that its working in your new.html.erb you have a new action inside your cards_controller, and inside this action you have something like: #card = Card.new
Well, if you want to put this form in another view, like in the application.html.erb you need to set first your #card variable, so you can do something like:
# application_controller:
before_filter :new_card
def new_card
#card = Card.new
end
be aware that all the controller that inherits from application controller will set this #card variable
#instance_variable
The underlying problem here is that you're calling a partial - by design, these are meant to give you the ability to call the functionality the file contains anywhere in your application
The problem you have is you're referencing an #instance_variable directly in your partial.
This isn't normally an issue - if you're using partials like you were originally (to modularize views), it should be okay. The problems arise when you try and use the partials in a more generalized way, as you are doing now:
#app/views/controller/_form.html.erb
<%= form_for(#card) do |f| %>
This relies on the #card instance variable being made available, which won't be if you're loading the partial in any other controller than the cards_controller.
--
Fix
The way to fix this is to either populate the #card instance variable in the application controller (as described by edymerchk), or to pass the raw value through the locals hash of the partial call:
This will allow you to use the card local variable in your partial:
#app/views/controller/_form.html.erb
<%= form_for card do |f| %>
-
Alternatively, you could also set the #card instance variable, as recommended in another answer:
#app/controllers/application_controller.rb
Class ApplicationController < ActionController::Base
before_action :set_card
private
def set_card
#card = Card.new
end
end

Load Rails partial with passed values using AJAX?

In my Rails app users have folders, and inside these folders are posts that they can add. Right now I have the folders displaying in my view like this:
<% current_user.folders.each do |folder| %>
<a href='#' id="addSubmissions">
<div id="post-container">
<%= folder.title %> <p id="created-time">Created <%= folder.created_at.strftime("%e/%-m") %></p>
</div>
</a>
<% end %>
What I'd like to do is load the submissions associated with a folder into a div when the #addSubmissions link is clicked. I've tried testing it out with this:
$('#addSubmissions').click(function(){
$('#post-container').append('<%= render :partial => 'contents', :locals => {:folder => folder } %>');
});
But it seems like that render code actually needs to be local beforehand.
The _contents.html.erb partial works, and is pretty simple:
<%= folder.title %>
<% folder.submissions.each do |i| %>
<%= i.title %>
<% end %>
How could I go about doing this? Again, I want to be able to click the link of a folder and load the submissions inside the folder into a div in the view. I'm thinking AJAX might be the solution, but I'm pretty new to Ruby so I don't know how to implement this.
This way it won't work. You need contoller method, which responds to JS, because you are fetching pure ruby variables.
Instead of:
<a href='#' id="addSubmissions">
you might try:
<%= link_to folder_content_path(folder), :remote=>true, :class=> "addSubmissions", :id=>folder.title %>
<div class="post-container" id="<%= folder.title %>">
<%= folder.title %> <p id="created-time">Created <%= folder.created_at.strftime("%e/%-m") %></p>
</div>
or other method name you want. Also note, that ID should be unique for page, otherwise you won't get expected result. Here I use folder name as ID, it probably unique, and it is easy way to find div we want modify with JS.
def folder_content
#folder=Folder.find(params[:id])
respond_to do |f|
f.js
end
end
folder_content.js.erb:
$("#"+"<%=#folder.title %>").append('<%= j render :partial => 'contents', :locals => {:folder => #folder } %>');

What's the cleanest way to add a class attribute to an html element in a view in rails

I'm writing some Rails code for a partial view, and I want it to only show a comment field if somebody is already logged onto a site here.
If the page is viewed by someone who isn't a member of the site yet, the shared/comment_not_logged_in fragment should be passed in.
However, I'm totally stumped as to why I can't run the same check to decide if the page should add the class attribute "missing_your_voice" to the enclosing div element here:
<li class="user_submission_form bubble comment_form <% "missing_your_voice" if not current_user %>">
<% if current_user %>
<%= image_tag(current_user.avatar(:comment), :class => "profile_pic") %>
<% form_for [parent, Comment.new] do |f| %>
<%= render "comments/form", :f => f %>
<% end %>
<% else %>
<%= render :partial => 'shared/comment_not_logged_in' %>
<% end %>
</li>
The same idiom, "missing_your_voice" if not current_user returns the string in irb, and also in the console debugger.
What am I doing wrong here?
You forgot an =. Replace <% by <%=, so that you get:
<%= "missing_your_voice" if not current_user %>
Remember that <% ... %> will only run Ruby code, but not display anything. Using <%= ... %> will run the code and display the result of the expression.
As molf already pointed out, there's a missing = on your view.
It should be <%=.
Other than that, be sure to make your controller method available to your view by calling helper_method in your controller.
Take a look on the documentation if needed.

Resources