How to conditionally display variables with EJS - ejs

This question may seem duplicate, but checking out the related questions didn't give satistfying answers.
Is there a better way of outputing (writing) variables in EJS, other then the commonly suggested
<% if (user) { %><%= user.name %><% } %>
I am searching for something like
<% if (user) {write(user.name)} %>
The closest thing I found was
<%= user.name ? user.name : '' %>
in this good post from 2015: https://blog.joeandrieu.com/2013/10/16/how-to-conditionally-display-variables-with-ejs/, but this approach fails, at least in Node 10, as I get Cannot read property 'name' of undefined. Am I doing it wrong? Or is there another way?

Check if user object is undefined. Use this:
<%= typeof user != 'undefined' ? user.name : '' %>
Alternatively you can attach your user object on locals , so you can use it this way:
<%= user.name ? user.name : '' %>

Related

collection_radio_buttons: how do you wrap a tag around each radio button?

collection_radio_buttons() is defined in the rails 5.1 docs like this:
collection_radio_buttons(
method, collection,
value_method,
text_method,
options = {},
html_options = {}, &block
)
There is no explanation in the docs for what the options argument is. The simple_form docs say that there is an option called item_wrapper_tag.
I've been trying this:
<%= form_for(:an_article, url: "blah") do |f| %>
<%= f.collection_radio_buttons(
:author_id, Author.all,
:id,
:name_with_initial,
{item_wrapper_tag: :div} #<=== HERE *****
)
%>
<% end %>
I've tried every combination of symbols and strings for the key, item_wrapper_tag, and the value, div, and nothing succeeds in wrapping each radio button in a div.
Does anyone know if rails has a similar option as item_wrapper_tag?
Okay, I figured it out:
<%= form_for(:an_article, url: "blah") do |f| %>
<%= f.collection_radio_buttons(
:author_id, Author.all,
:id,
:name_with_initial,
) do |b|
%>
<div>
<%= b.radio_button %>
<%= b.label %>
</div>
<% end %> #collection_radio_buttons do block
<% end %> #form_for do block
radio_button and label are builtin methods for the |b|uilder object:
The argument passed to the block is a special kind of builder for this
collection, which has the ability to generate the label and radio
button for the current item in the collection... Using it, you can
change the label and radio button display order or even use the label
as wrapper...
Additional info:
collection_radio_buttons(object, method,
collection,
value_method, text_method,
options={}, html_options={}, &block)
collection: For each element in collection, a radio button and label tag is created.
value_method: Called on each element in collection, and the return value is assigned to
the value attribute of the radio button.
object.method: If the return value of object.method is equal to the value attribute of a radio button,
the radio button gets a checked="checked" attribute.
text_method: Called on each element in collection, and the return value is used as
the text for the label tag.
options: Unknown purpose.
html_options: Used to specify additional html attributes for the radio button, e.g. {class: 'group1'}
When you use form_for(), the object argument is the object encapsulated by f, so you omit the object argument:
f.collection_radio_buttons(method,
collection,
value_method, text_method,
options={}, html_options={}, &block)
and method is called on this object:
|
V
form_for(:an_article, url: "blah") do |f|
Try using the gem simple_form for your forms. Then the code below should work already.
Add gem simple_form in your Gemfile.
Run bundle install
Run rails generate simple_form:install
Then create a simple_form in your view that would look like this:
<%= simple_form_for #post do |f| %>
<%= f.collection_radio_buttons( :author_id, Author.all, :id, :name_with_initial, item_wrapper_tag: :div) %>
<% end %>
Note: I just followed the form from the collection_radio_buttons from APIDock.
This might do the trick. :)

form_for does not pass the required value when user submits blank form [duplicate]

This question already has answers here:
Rails 4: How do I handle a submitted form where nothing was selected?
(3 answers)
Closed 7 years ago.
I have the following form:
# controller
def edit
#doc = HomeworkDocument.find(params[:id])
end
# view
<%= form_for #doc,
url: student_homework_document_path(student_id: #doc.submitter_id,
id: #doc.id),
html: { multipart: true } do |f| %>
<%= f.label :file1 %>
<%= f.file_field :file1 %>
<%= f.label :file2 %>
<%= f.file_field :file2 %>
<%= f.submit "Submit" %>
When the user submits either one or both of file1 and file2, the form works fine. However, when the user clicks submit without any file, exception is raised:
param is missing or the value is empty: homework_document
due to my strong param specification:
def doc_grader_params
params.require(:homework_document)
.permit(:file1, :file2)
end
The param that gets passed is (notice no homework_document is passed):
Parameters:
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"QJirOW/HQ3sv8AR/yArW6cQ2bmvz0j5D8G6czu45lLA=",
"commit"=>"Submit grading",
"student_id"=>"4",
"id"=>"21"}
Why does this happen and how to to include an (empty) homework_document hash in param even when the user submits blank form?
To include an empty homework_document hash, you have two options:
Assuming you do not want to override the :file1, :file2 attributes if submission is empty, add an empty hidden_field in the form and allow that to pass in via strong parameters, but do virtually nothing to the parameter. Like so:
<%= hidden_field_tag 'homework_document[placeholder]', 'do nothing' %>
def doc_grader_params
params.require(:homework_document)
.permit(:file1, :file2, :placeholder)
end
If you do want to override the attributes (erasing files if empty), place two hidden_fields of name homework_document[file1] and homework_document[file2] before the file inputs and set their value to ''(or whatever defaults you have). Because parameters extraction gets the last occurrence of any repeated key in the query string, this should work.
This approach is similar to the check_box empty submission approach outlined in:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box

Rails 4: undefined method `permit' for "xxxx xxxx":String

I have a search model that I hope to use in conjuction with sunspot to handle all searches across different models. I'm stuck before I even have gotne started.
Here is the form...that appears in the header of all the web pages on my site.
<%= simple_form_for #search, :url => searches_path, :method => :post do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", class: "btn btn-primary" %>
<% end %>
In my searches_controller
def search_params
params.require(:search).permit(:search)
end
In my Search.rb
attr_accessor :search
When I plug in my name into it I get this error
undefined method `permit' for "simon walsh":String
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"1Tez0pnMILEciLR6j+li+qSeO4NYBj3XsB6dYG07RymsiNUNSAGI5ztpMiD4JNAtTnqwJYdHTpPBRqGduWHjBw==",
"search"=>"simon walsh",
"commit"=>"Search"}
I am confused. This is clearly a simple error with the way I am posting the params. Any help?
Use this:
def search_params
params.require(:search).permit!
end
Instead of this:
def search_params
params.require(:search).permit(:search)
end
This issue may occur because of string parameter in params["search"], while in controller you are using .permit(:search), or maybe you have an attribute and model name that are the same.

Rails Tutorial 3.2 Chapter 8 error: NoMethodError in SessionsController#create

I'm going through the rails tutorial and my login page is throwing an exception after exercise 8.1.5 when I click the login button with no email or pw entered:
http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec-rendering_with_a_flash_message
Error:
NoMethodError in SessionsController#create
undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'
SessionsController matches the final code exactly for the Create method
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email].downcase) #line 7
if user && User.authenticate(params[:session][:password])
#will fill this in later
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
end
end
I did change the button label to Log in instead of "Sign in" as that is too confusing with "Sign up", but I didn't think that would create the problem. sessions\new.html.erb
<% provide(:title, "Log in") %>
<h1>Log in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:sesssion, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Log in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
This post hints that I need a method in my user model, but adding that didn't help:
NoMethodError in SessionsController#create
I tried adding this to user.rb, but it didn't help
results from find_by_email executed in function differs from console:
def self.authenticate(email, submitted_password)
user = find_by_email(email)
return user.nil? ? nil : user
end
Any ideas would be greatly appreciated!
I've looked at the example from the book and your code and I noticed this line
if user && User.authenticate(params[:session][:password])
your User.authenticate should be lowercased to user.authenticate. Revert back to your original code.
I have just had the same problem and found that in fact i needed [:sessions] with an s on the end!
So line reads
if user && User.authenticate(params[:sessions][:password])
Hope this helps someone in the future!
I had the same problem after doing exercise 1 in chapter 8 where I replaced the use of form_for with form_tag. This resulted in the name attributes in the generated input form fields changing from name="session[email]" and name="session[password]" to name="email" and name="password". Subsequently, I needed to access the params using params[:email] and params[:password] instead of params[:session][:email] and params[:session][:password].
My new Sessions controller looks like this:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email].downcase)
if user && user.authenticate(params[:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
end
This solved the problem for me. Hope this is helpful to someone else.
In this section from the tutorial chapter 8, all instances of [:session] should be [:sessions]. Hope that helps.
class SessionsController < ApplicationController
.
.
.
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
.
.
.
end
Could you confirm the word 'session' in app/view/session/new.html.erb spelling correct?
I see you wrote:
form_for(:sesssion, url: sessions_path) do |f|
But in app/controllers/sessions_controller.rb, you wrote:
user = User.find_by_email(params[:session][:email].downcase) #line 7
They must be the same.

searchresult usin sphinx

i am using sphinx beta and thinking-sphinx to perform search functionality..the search i
wann should search for the word i entered in the database.which is populated with data already.
so in my application Mydoc,i got articlesmodel and controller.. articles is db is populated with data.
i wann to search for the data in articles..so far i ve done with following things but not getting the search result
=> created new search controller
def index
#articles = Article.search params[:search]
end
=> articles.rb(model)
define_index do
indexes name, :sortable => true
indexes description
indexes title, :sortable => true
end
def self.search(search)
ThinkingSphinx::Search
end
=> searches/index.html.erb
<%= form_tag do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "search", :name => nil %>
</p>
<% end %>
BUT WEN I CLICK ON THE SEARCH BUTTON ITS ASKING FOR CREATEACTION ?????
PLEASE COULD U HELP TO GET SEARCH RESULT
Your form is making a POST request to your SearchController, and that is interpreted as a call to the create action. Try using a GET request instead with your form - something like this:
<%= form_tag '', :method => :get do %>