I've got the following code in my show.html.erb file:
<p>
<b>Status:</b>
<% if #server.serverUp?.to_s == "Up" %>
<% #server.update_attribute(#server.serverStatus, 'Up') %>
<span style="color: green;"> <%= #server.serverUp? %></span>
<% else %>
<span style="color: #ff0000;"> <%= #server.serverUp? %></span>
<% end %>
</p>
My main concerns is with the line <% #server.update_attribute(#server.serverStatus, 'Up') %> which breaks my app from working. This line is supposed to save the status of the Server, whether it is "Up" or "Down", and save it in 'servers' table under the 'serverStatus' column.
However, when I go to http://localhost:3000/servers/id_of_server, where 'id_of_server' is a number from 1-300, the following error message appears:
NoMethodError in Servers#show
Showing C:/SIS/app/views/servers/show.html.erb where line #18 raised:
undefined method `=' for #<Server:0x60b9358>
Extracted source (around line #18):
15: <p>
16: <b>Status:</b>
17: <% if #server.serverUp?.to_s == "Up" %>
18: <% #server.update_attribute(#server.serverStatus, 'Up') %>
19: <span style="color: green;"> <%= #server.serverUp? %></span>
20: <% else %>
21: <span style="color: #ff0000;"> <%= #server.serverUp? %></span>
I don't seem to understand the error message, as I haven't used an equal sign in the extract of code provided. Any help would be appreciated.
If you guys need any more info let me know.
Thanks in advance
Edit: While I'm at it, I just wanted to ask whether I'm not following the RoR conventions by putting that type of code into the show.html.erb file as opposed to somewhere else? Because in the same file I also have another algorithm which reads all the attributes of a model, puts it into an array, and displays only the unique values.
Thanks
You should write:
<% #server.update_attribute(:serverStatus, 'Up') %>
And yes: you should not update models in view. In your case it could cleanly live in a before_save or why not in an after_initialize callback in the model I guess.
Lastly: in Ruby, convention is snake case so server_status instead of serverStatus
Related
Rails each do method is acting strangely and I do not know why.
controller
def index
#fabric_guides = FabricGuide.with_attached_image.all.order(:name)
end
index.html.erb
<div class="guide-items">
<%= #fabric_guides.each do |fabric| %>
<div class="guide-container">
<%= link_to fabric_guide_path(slug: fabric.slug) do %>
<%= image_tag fabric.image if fabric.image.attached? %>
<% end %>
<div class="guide-info">
<p class="g-name">
<%= link_to fabric.name,
fabric_guide_path(slug: fabric.slug) %>
</p>
</div>
</div>
<% end %>
</div>
I have two FabricGuide records so I expect two "guide-container" but I get three. Or more precisely I get two guide containers and a third block of text containing all the content from the last FabricGuide record.
I have almost an identical setup for articles and have never encountered this problem. I'd happily share more information if needed. Thank you!
Please remove = equal sign from your each loop of view code
like below :-
<% #fabric_guides.each do |fabric| %>
...
...
<% end %>
you have used this <%= #fabric_guides.each do |fabric| %> in your view that's why it shows all record in DOM.
The expression for erb tags is <% %>
now if we want to print that tag too then we apply <%= %>
I am fairly new to rails and I am trying to the shopping cart html view to the site admin when a order is made. The email portion is working just fine with simple html but when I add the ruby code to render the views page I get the following error:
NoMethodError in Charges#create
Showing /home/ubuntu/workspace/app/views/order_mailer/order_email.html.erb where line #7 raised:
undefined method `size' for nil:NilClass
Extracted source (around line #7):
5
6
7
<%= render "carts/shopping_cart", size: #order_items.size %>
Rails.root: /home/ubuntu/workspace
Application Trace | Framework Trace | Full Trace
app/views/order_mailer/order_email.html.erb:7:in `_app_views_order_mailer_order_email_html_erb___1590505826361550286_70123907983000'
app/mailers/order_mailer.rb:11:in `order_email'
app/controllers/charges_controller.rb:10:in `create'
From what I have read I think I need to add locals to my render code but I am confused on what exactly locals are and what they would be in my code. If I am completely off track and this error has nothing to do with locals I would appreciate some guidance in the right direction.
Thanks!
order_email view:
<h1>You have a new order </h1>
<%= render "carts/shopping_cart", size: #order_items.size %>
The view I am trying to render in the email:
<% if !#order_item.nil? && #order_item.errors.any? %>
<div class="alert alert-danger">
<ul>
<% #order_item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if #order_items.size == 0 %>
<p class="text-center">
There are no items in your shopping cart. Please <%= link_to "go back", root_path %> and add some items to your cart.
</p>
<% else %>
<% #order_items.each do |order_item| %>
<%= render 'carts/cart_row', product: order_item.product, order_item: order_item, show_total: true %>
<% end %>
order_mailer.rb:
class OrderMailer < ApplicationMailer
default from: "xxxx#gmail.com"
def order_email(order_items)
#order_items = order_items
mail(to: "xxxx#gmail.com", subject: "Your subject")
end
end
I believe locals are only used when doing a render partial, which you should be able to do for this but you'd need to make a few adjustments.
Each of the partials' filename need to be adjusted to have and underscore in front of them, but you still reference them without the underscore (I know it's a bit confusing).
So rename carts/shopping_cart to carts/_shopping_cart
and then change where it's referenced to:
<%= render partial: "carts/shopping_cart", locals:{size: #order_items.size} %>
Do the same sort of thing with 'carts/cart_row'
I am having a weird issue where my rails application seemingly isn't reading the local variable passed to the partial, but only inside of form_for.
I have a set up a button where a user can bookmark an object, let's call it zoo.
The code looks like this:
Zoo Listing View:
<li><%= render 'directory/bookmarks', zoo: zoo %></i></li>
Then the directory/bookmarks partial:
<% if user_signed_in? %>
<% if current_user.has_zoo_bookmarked_already? %>
<%= form_for(current_user.bookmarks.find_by_zoo_id(zoo.id), html: { method: :delete }, remote: true) do |f| %>
<%= button_tag do %>
<button class="btn btn-lg btn-block btn-primary">remove bookmark
<% end %>
<% end %>
<% else %>
<%= form_for(current_user.bookmarks.build(zoo_id: zoo.id)) do |f| %>
<%= f.hidden_field :zoo_id, value: zoo.id %>
<%= button_tag do %>
<button class="btn btn-lg btn-block btn-primary">bookmark
<% end %>
<% end %>
<% end %>
<% else %>
<% end %>
Anyway, the problem is the zoo.id on the 3rd line is not being evaluated. I get this error.
undefined method `model_name' for NilClass:Class
The weird part is that locals are being read on the page.
If I place this code snippet <%= zoo.id %> anywhere on the page, I get the id. Then, the find_by_zoo_id is being evaluated also...if I put 255 a hardcoded number, it works. Or if I set it to a variable, #id = 255 and then pass in the #id, it works.
The zoo.id only does not work inside of the form_for for some reason. If I set it to an instance variable on the page, #id = zoo.id, that doesn't work either.
Any ideas? I'm sure it is something minor.
EDITED:
The relationship is has_many :through. Forgot to mention, I use this code for a different association in the same application and it works fine.
That error you're getting suggests current_user.bookmarks.find_by_zoo_id(zoo.id) is nil. find_by_zoo_id might be returning you nothing
Of course it was -- I was iterating through a list of zoos with bookmarks, but not all of them would be bookmarked by the user. I just had to add an additional condition.
<% if user_signed_in? %>
<% if current_user.has_zoo_bookmarked_already? && current_user.bookmarks.find_by_zoo_id(zoo.id) %>
#....
So being new to rails I seem to be stuck on creating a loop within a loop to process the information.
I am getting:
can't convert Symbol into Integer line #11
The line in question is:
Host <%= servicedetails[:hostidn] %> - <%= servicedetails[:status] %>
And here is the full version below. Being new Im clueless and open to suggestions.
<div>
<% #service_hash[:service_list].each do |servicesinfo| %>
<ul>
<li>
<ul>
<li>
<h2><%= servicesinfo[:service_name] %><h2>
</li>
<% servicesinfo.each do |servicedetails| %>
<li>
Host <%= servicedetails[:hostidn] %> - <%= servicedetails[:status] %>
</li>
<% end %>
</ul>
</li>
</ul>
<% end %>
</div>
the JSON equivalent of this hash is
{"status":"successful","service_list":[{"service_name":"oozie","status":"RUNNING","status_message":"Running Master Service","host":"1"},{"service_name":"single-namenode","status":"RUNNING","status_message":"Running Service","host":"1"},{"service_name":"single-database","status":"RUNNING","status_message":"Running Service","host":"1"},{"service_name":"datanode","status":"RUNNING","status_message":"Running Service","host":"1"},{"service_name":"secondarynamenode","status":"RUNNING","status_message":"Running Service","host":"1"},{"service_name":"web","status":"DEAD","status_message":"Running Master Service","host":"1"},{"service_name":"tasktracker","status":"RUNNING","status_message":"Running Service","host":"1"},{"service_name":"jobtracker","status":"RUNNING","status_message":"Running Master Service","host":"1"}]}
You're already iterating over the array of hashes with service info (renamed to make sense):
<% #service_hash[:service_list].each do |service_info| %>
...
<% end %>
Iterating over service_info would return [key, value] pairs--likely not what you want.
Access the information from service_info directly, as you already do with :name
<%= service_info[:host] %> - <%= service_info[:status] %>
I don't see anything called :hostidn in that hash, just :host; not sure if that's a typo, or if you're expecting additional data not shown.
I have a repeated line which outputs something like:
Call John Jones in -3 days (status)
I have a helper called show_status(contact,email) which will output whether that particular email had been sent to that particular contact.
If it is "sent," then that entire line should show up as "strike out."
Similarly, if the number of days is -3 (<0), the line should be formatted in red.
Here's my hack, but there must be a cleaner way to put the logic into the controller?
I hard-code a value that wraps around the lines I want formatted, and assign the value based on a separate call to the same helper:
<% for call in #campaign.calls %>
<% if !show_call_status(#contact,call).blank? %>
<%= strike_start = '<s>'%>
<%= strike_end = '</s>' %>
<% end %>
<p>
<%= strike_start %>
<%= link_to call.title, call_path(call) %> on
<%= (#contact.date_entered + call.days).to_s(:long) %> in <%= interval_email(#contact,call) %>
days
<%= make_call(#contact,call) %>
<span class='status'><%= show_call_status(#contact,call) %></span>
<%= strike_end %>
</p>
<% end %>
I guess what I'd like to do is not have the if statement in the View. Not sure how to do this.
Basically, I would put a class on the p tag based on the status and have the CSS decide what needed to be done.
So the view:
<% for call in #campaign.calls %>
<p class="<%= call_status_class(#contact, call) %>">
<%= link_to call.title, call_path(call) %> on
<%= (#contact.date_entered + call.days).to_s(:long) %> in <%= interval_email(#contact,call) %>
days
<%= make_call(#contact,call) %>
<span class='status'><%= show_call_status(#contact,call) %></span>
</p>
<% end %>
And another helper:
def call_status_class(contact, call)
# do what you have to do to figure out status
if overdue
return 'overdue'
elsif called
return 'called'
else
return 'standard'
end
end
Then in CSS:
.standard {
...
}
.overdue {
color: red;
}
.called {
text-decoration: line-through;
}
Pick and choose. I can't really give you full fledged solution without seeing all the helper functions. Hope this helps.