If respond_to? not returning anything - ruby-on-rails

I have a bit of code that is supposed to be checking whether or not a method call exists for an attribute, it seems neither the if or else are returning anything...
%h2= #post.title
.row
.col-sm-12
= render "blog_meta", :post => #post
#text_body
= #post.content
%hr
- if #post.comments.count > 0
%h2 Comments
#comments
- #post.comments.where(:original_id => nil).each do |comment|
.comment
.profile
%img{:src => "/assets/profile_image_sample.jpg"}
.message
.username
- if comment.user.respond_to?('username')
.username= comment.user.username
- else
.username= comment.user.first_name
= comment.content
- logger.info "LOGGER--->>" + comment.user.first_name
.reply-link
%a{:href => "#"} Reply to Comment
- if comment.replies.count > 0
- nesting = 0
- comment.replies.each do |comment|
= render "comment", :comment => comment, :nesting => nesting
%hr
= render "submit_comment"
However if I simply = comment.user.first_name with no conditionals then it works fine..

most likely the user responds to username but it is blank or nil. You might want to do this instead
- if comment.user.username.blank?
.username= comment.user.first_name
- else
.username= comment.user.username
respond_to is used to check if a method is defined for the object. It will return true if the method is defined for the object. It does not concern what the output of that method is.

Related

Render partials inside loop in Rails 5

Question: How do I make a partial (that has to be generic) loop through different variables?
I have a tabbed page where I want to use a partial to avoid duplicating my HTML. The tabs are "Videos" and "Articles". It's the exact same HTML but I want to iterate through #videos for videos and #articles for articles.
The idea was to make the product partial completely generic and then somehow pass in #videos or #articles that I want to iterate through.
Partial: _product.html.slim
.col-md-5
.thumbnail
.thumb.spacer-sm
- if product.image.blank?
iframe allowfullscreen="" frameborder="0" mozallowfullscreen="" src="https://player.vimeo.com/product/#{product.vimeo_id}" webkitallowfullscreen=""
- elsif product.vimeo_id.blank?
= image_tag(product.image.url,
class: 'img img-responsive img-rounded')
.caption
.content-group-sm.media
.media-body
h6.text-semibold.no-margin
= product.name
small.text-muted
| by
= product.user.name
- unless product.price.blank?
h6.text-success.media-right.no-margin-bottom.text-semibold
| $
= product.price
= product.description
.panel-footer.panel-footer-transparent
.heading-elements
ul.list-inline.list-inline-separate.heading-text
li
= link_to 'Delete', product_path(product), method: :delete
li
= link_to 'Edit', edit_product_path(product)
HTML view rendering the partial:
.page-container.spacer-minus
.page-content
.row
.col-md-4
.sidebar-default.sidebar-separate
.sidebar-content
.content-group
.panel.no-border-radius-top
ul.navigation
li.navigation-header Navigation
li.active
a data-toggle="tab" href="#videos"
i.icon-video-camera2
| Videos
li
a data-toggle="tab" href="#articles"
i.icon-graduation
| Articles
.col-md-8
.tab-content
#videos.tab-pane.fade.in.active
.row
- #videos.each do |product|
= render 'shared/product'
#articles.tab-pane.fade
.row
- #articles.each do |product|
= render 'shared/product'
I just need my loop to understand what variable I want to iterate through. I cannot include #video or #article in the partial since that will defeat the purpose of having a generic partial.
With this implementation, I get the error:
undefined local variable or method `product' for #<#<Class:0x007fc58053ae60>:0x007fc58884ea68>
Try this code:
#videos.tab-pane.fade.in.active .row -
#videos.each do |video|
= render 'shared/product', product: video
#articles.tab-pane.fade .row -
#articles.each do |article|
= render 'shared/product', product: article
Hi this is pretty stuff if you want articles to come after the videos then try this.
= render partial: "product", collection: #videos
= render partial: "product", collection: #articles
this will remove the loop from your main view but in your case you are not using locals try this
.row
- #videos.each do |video|
= render 'shared/product', locals: {product: video}
.row
- #articles.each do |article|
= render 'shared/product' , locals: {product: article}
It will work.

Rails error undefined method `include?' for nil:NilClass

Having a bit of a rough time on this example, my code reads as:
view
<% monthNumber = (Time.now - 1.month).strftime("%m") #
yearNumber = (Time.now).strftime("%Y") #
monthWord = (Time.now - 1.month).strftime("%B")#
monthYear = "#{monthNumber}-#{yearNumber}"
createdAtCount = 0
creationDateCount = 0 %>
<h1>Stats for <%= monthWord %></h1>
<p><%= monthNumber %>-<%= yearNumber %></p>
<% #votsphonebooks.each do |entry| %>
<% if entry.CreationDate.include? monthYear %>
<p>test</p>
<% end %>
<% end %>
controller
def reports
#votsphonebooks = Votsphonebook.order("id DESC").paginate(:page => params[:page], :per_page => 5000)
end
I can, for example in the loop, run through all the first names, so the loop is working OK, but as soon as I try to test if the 'CreationDate' includes '10-2016' (which also works fine), it gets the error.
CreationDate column has the format: 11-10-2016 - 10:51 AM
Thanks!

Parameter in AJAX request

I have a view which contain multiple links:
<% a.each do |q| %>
<%= link_to "stock it",
{ :action => "stock",
:qid => q.question_id,
:qur => q.question_answers_url,
:qti => q.title } ,
:remote => true %>
<div id="<%= "stock" + q.question_id.to_s %>"></div>
<% end %>
Each link generate AJAX-request. Here is a controller:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
respond_to do |format|
format.js { render :layout=>false }
end
end
Now return to the view. Each link has a 'div' with unique id='stock'. When user press the link I need to add text to specific div with corresponding id.
I have a stock.js.erb file:
$("#stock<number>").html("some text");
How can I pass div-id to stock.js.erb and how can I use it ?
Common use is to add object.id to your DOM id. That what you exactly did:
<div id="<%= "stock_#{q.question_id}" %>"></div>
Then in your controller you shoud define your question_id or your exact question:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
#question_id = params[:qid]
end
Now it will be shared with your stock.js.erb file:
$("#stock_<%= #question_id %>").html("some text");

form_for, fields_for and two models

I have form that create two objects and save them to database.
I want to do next things:
save data in database (booth objects)
validate fields (I have validation in model)
and if validation fail, I want to populate fields with entered data
edit action for this form
Problems:
If I use #report I get:
Called id for nil, which would
mistakenly be 4 error
(can't find object). I have in controller, in encreate action #report = ReportMain.new and in action that render that view.
When I use :report_main (model name) it works, it save data to database, but I can't get fields populated when validation fails.
Questions:
What to do with this two models to make this to work (validation, populating fields, edit)?
Can you give me some advice if approach is wrong?
My view looks like this:
<%= form_for(#report, :url => {:action => 'encreate'}) do |f| %>
<%= render "shared/error_messages", :target => #report %>
<%= f.text_field(:amount) %>
<% fields_for #reporte do |r| %>
<%= r.check_box(:q_pripadnost) %>Pripadnost Q listi
<%= select_tag('nacinpakovanja',options_for_select([['Drveno bure', 'Drveno bure'], ['Kanister', 'Kanister'], ['Sanduk', 'Sanduk'], ['Kese', 'Kese'], ['Posude pod pritiskom', 'Posude pod pritiskom'], ['Kompozitno pakovanje', 'Kompozitno pakovanje'], ['Rasuto', 'Rasuto'], ['Ostalo', 'Ostalo']])) %>
<%= r.text_field(:ispitivanjebroj) %>
<%= r.text_field(:datumispitivanja) %>
<% end %>
<input id="datenow" name="datenow" size="30" type="text" value="<%= #date %>">
<div class="form-buttons">
<%= submit_tag("Unesi izvestaj") %>
</div>
<% end %>
encreate actin in ReportController:
def encreate
#report = ReportMain.new
#reporte = ReportE.new
#reportparam = params[:report_main]
#report.waste_id = params[:waste][:code]
#report.warehouse_id = Warehouse.find_by_user_id(current_user.id).id
#report.user_id = current_user.id
#report.company_id = current_user.company_id
#report.amount = #reportparam[:amount]
#report.isimport = false
#report.isfinished = false
#report.reportnumber = ReportMain.where(:company_id => current_user.company_id, :isimport => false).count.to_i+1
if #report.save
#reporte.report_main_id = #report.id
else
redirect_to(:action => 'exportnew')
return
end
#reporte.vrstaotpada = params[:vrstaotpada]
#reporte.nacinpakovanja = params[:nacinpakovanja]
#reporte.ispitivanjebroj = #reportparam[:ispitivanjebroj]
#reporte.datumispitivanja = #reportparam[:datumispitivanja]
#reporte.q_pripadnost = #reportparam[:q_pripadnost]
#reporte.datumpredaje = #date
if #reporte.save
redirect_to(:action => 'show', :id => #reporte.id)
else
redirect_to(:action => 'exportnew')
end
end
I think your problem in this case is that you use redirect_to instead of render. When you use redirect_to then you lose all the variables from your current action. I would probably do something like this in your encreate action:
if #reporte.save
render :show
else
render :exportnew
end
When you use render then it will use the variables from the current action but the view from the action you send to the render method. So when form_for is called with the #report variable, it is already populated with the values that was sent to encreate. Just make sure that you use the same variable names in the different actions but it looks like you do that already.

refactor conditions within haml view

beside the fact that accessibility standards discourage the use
of a link pointing to the current page, how I am supposed to
refactor the following view code?
#navigation
%ul.tabbed
- if current_page?(new_profile_path)
%li{:class => "current_page_item"}
= link_to t("new_profile"), new_profile_path
- else
%li
= link_to t("new_profile"), new_profile_path
- if current_page?(profiles_path)
%li{:class => "current_page_item"}
= link_to t("profiles"), profiles_path
- else
%li
= link_to t("profiles"), profiles_path
...
Thank you.
# helpers
def current_page_class(page)
return :class => "current_page_item" if current_page?(page)
return {}
end
-# Haml
#navigation
%ul.tabbed
%li{current_page_class(new_profile_path)}
= link_to t("new_profile"), new_profile_path
%li{current_page_class(profiles_path)}
= link_to t("profiles"), profiles_path
...
#navigation
%ul.tabbed
%li{:class => current_page?(new_profile_path) ? "current_page_item" :nil }
= link_to t("new_profile"), new_profile_path
%li{:class => current_page?(profiles_path) ? "current_page_item" :nil }
= link_to t("profiles"), profiles_path
...
Looks like a good case for a partial to me.

Resources