Problems with passing variables to a partial - ruby-on-rails

I'm using the partial "infowindow" (app/view/tech/_infowindow.html.erb) to populate a google map marker using:
new_marker = GMarker.new([t.lat, t.lng], :icon => icon, :title => t.summary, :info_window => (render_to_string :partial => "infowindow", :object => t))
but i'm getting a very odd error. When I simply put:
<%= debug(infowindow) %>
I get the full output of the hash. But when I try to reference any of the individual attributes like:
<%= infowindow.summary %>
I get thrown an undefined method `summary' for nil:NilClass even though the attribute shows up in the debug output for the entire hash. Why can I only access the entire hash and not its individual attributes in the partial?
EDIT: The top part of the returned hash:
!ruby/object:Ticket
attributes:
The model being used is a Ticket object if that helps.

What you are trying to do is call the method summary on the infowindow hash which does not exist in the Hash Class and hence the error. To access individual hash elements try this
<%= infowindow["summary"] %>

Related

Rails 5.2 partial counter: "undefined local variable or method" error

Per the information box on https://guides.rubyonrails.org/layouts_and_rendering.html#using-partials:
Rails also makes a counter variable available within a partial called
by the collection, named after the title of the partial followed by
_counter. For example, when rendering a collection #products the partial _product.html.erb can access the variable product_counter
which indexes the number of times it has been rendered within the
enclosing view.
However, I am getting and error when referencing the counter in my partial. Here is the parent view:
<%= render partial: 'comments/comment_template', collection: #post.comments, as: :c %>
Here is the relevant part of _comment_template.html.erb:
<%= comment_template_counter %>
And here is the error:
undefined local variable or method `comment_template_counter' for #<#<Class: [etc.]
What am I missing?
I believe the documentation is incorrect. As pointed out by pedroadame at https://coderwall.com/p/t0no0g/render-partial-with-collection-has-hidden-index, when using the :as option, I need to use the name of the variable rather than the name of the partial.
Furthermore, if elsewhere in my app I am only rendering the partial once instead of as a collection, I need to sidestep the (same) error message by checking whether the counter is defined.
So in my partial, this now works:
<%= c_counter if defined? c_counter %>

Render partial collection with association

I am trying to render partials for a collection of #entries to a shared view.
In one controller, I am doing it directly to render all the #entries in the view.
<%= render(:partial => '/shared/entry', :collection => #entries) %>
On another controller, I am doing it through bookmarks. As a result, the collection is #bookmarks.entries
<%= render(:partial => '/shared/entry', :collection => #bookmarks.entries) %>
Here is my /shared/_entry.html.erb :
<div>
<%= link_to_unless_current entry.tag_list, tag_path(entry.tag_list) %>
</div>
I get the following error from the Bookmark controller, but the other controller works fine:
undefined method `tag_list' for #<Bookmark:0x007fad659b32b8>
It looks like it happens because even thought the collection is #bookmarks.entries, it is still recognizing it as a Bookmark and not as an Entry. If I change the view to the following, it works on the Bookmark, but then fails on the other controller:
<div>
<%= link_to_unless_current entry.entry.tag_list, tag_path(entry.entry.tag_list) %>
</div>
How can I make the Bookmark collection just to have entries?
What's happening here is that you've used the wrong syntax by mistake, and it just happens that there is a method with the name you've used, existing in Rails/Ruby already.
If you are expecting this
#bookmarks.entries
to return a list of Entry objects, then it won't. If #bookmarks is a collection of Bookmark objects, and a #bookmark has_many :entries, and you want to get all entries associated with all the bookmarks, you would do something like #bookmarks.collect(&:entries).flatten.uniq.
So, the syntax is wrong, and it should break, except that it just so happens that the Enumerable module, which is included in the Rails collection class, has a method called "entries", which returns an array of the items, which in this case are all Bookmark objects. So, the partial is expecting an Entry and it's getting a Bookmark, and that's what that error is telling you: you're calling tag_list on a Bookmark object.

getting an undefined method error from "_user.html.erb" in Rails 3

If I am getting this error
undefined method impressionist_count' for nil:NilClass after trying to use this line inside _user.html.erb
<%= #user.impressionist_count+#user.microposts.sum(&:impressionist_count) %>
where does it need to be defined? I already have this inside user.rb
def impressionist_count
impressions.size
end
I tried it in various helpers but to no avail
When you "render #users" each user is accessible to the partial as the local variable "user". Your partial should look like:
<%= user.impressionist_count+user.microposts.sum(&:impressionist_count) %>
The method is defined, but the #user object is not. This should've been assigned in the controller in order for it to work inside your view, or your partial should've been provided an object when you're rendering it.
Maybe you have something like:
<%= render(:partial => 'user') %>
What you might need is this if you have a user variable:
<%= render(:partial => 'user', :object => user) %>
Errors including the phrasing "for nil" are an indication of an undefined value being used incorrectly.

working with custom hash array in Rails

I already posted a similar question but i got told to try and solve it myself and post here what i have so far.
What i'm doing is calling some xmlrpc methods to extract some data from an external app.
what i can do so far is display contents from a simple array as per below.
<% #attachment.each do |att| %>
<div class="item">
<%= image_tag att %>
</div>
What i want is to be able to pass a hash array similar to this:
{id:"1", content:"somedataaa", imgurl:"someurl.com/image.jpg"}
what i want is when the user clicks on an image to pass the id to a controller method so i can then go and get more data with the id provided and provide another view.
<% #hasharray.each do |att| %>
<div class="item">
<%= att.id %> //this could be hidden an only used to pass the id to a method
<%= image_tag att.url %> //add a link_to here somehow to route to a method on the controller.
</div>
I know how to do this with rails model data, but since this data is coming from an external xmlrpc i have to pass it as a hash array.
Could you please guide me to how i need to do this, is this the right way, or can i parse the hash array and somehow save it to a Rails model so i can then use the view as normal and have access to the routes.
attachments = [{ :id => 1, :url => 'images/1.jpg' }, { :id => 2, :url => 'images/2.jpg' }]
attachments.each do |attachment|
link_to image_tag(attachment[:url]), "/path/to/controller/#{attachment[:id]}/show"
end
Side note: Please follow proper naming conventions. Don't name variables "hasharray" or "hash" or "array" or anything similar. Make them meaningful. Please.
Reading this will help: http://www.ruby-doc.org/core-1.9.3/Hash.html
You can just pass the hash instead of a model, and us att[:id] instead of att.id.
If you really need it to be a model instead of a hash, you can look at Hashie, which provides several methods to convert a hash to a model:
https://github.com/intridea/hashie

How can you pass an object from the form_for helper to a method?

So let's say I have a form which is being sent somewhere strange (and by strange we mean, NOT the default route:
<% form_for #form_object, :url => {:controller => 'application',
:action => 'form_action_thing'} do |f| %>
<%= f.text_field :email %>
<%= submit_tag 'Login' %>
<% end %>
Now let's say that we have the method that accepts it.
def form_action_thing
User.find(????? :email ?????)
end
My questions are thus:
How can I make the object #form_object available to the receiving method (in this case, form_action_tag)?
I've tried params[:form_object], and I've scoured this site and the API, which I have to post below because SO doesn't believe I'm not a spammer (I'm a new member), as well as Googled as many permutations of this idea as I could think of. Nothing. Sorry if I missed something, i'm really trying.
How do I address the object, once I've made it accessible to the method? Not params[:form_object], I'm guessing.
EDIT
Thanks so much for the responses, guys! I really appreciate it. I learned my lesson, which is that you shouldn't deep-copy an object from a form, and that the parameters of a form are actually included when you submit it.
I will admit it's sort of disheartening to not know stuff that seems so obvious though...
you need to pass the "id" of your "#form_object" in the url and then lookup that object (assuming you have a model and using ActiveRecord)
It depends on how do you set up your routes. If you're using the default /:controller/:action/:id route, you can pass it as a parameter in the URL. Note that not the whole #form_object can/should be passed, but it's id or some other attribute to identify it instead. In this case, you should make your URL:
<% form_for #form_object, :url => {:controller => 'application',
:action => 'form_action_thing', :email => some_email} do |f| %>
<%= f.text_field :email %>
<%= submit_tag 'Login' %>
<% end %>
And in your controller
def form_action_thing
#user = User.find_by_email(params[:email])
end
You can pass parameters through the url, but when submitting a form the only thing that should (probably) be passed through the url is the record id for a RESTful record.
And it appears you didn't find out yet where your form data can be found in the params.
So
All the data from your form should end up in params[:form_object]. The actual value for :form_object is selected by Rails, it's probably coming from the object's class (too lazy to look that up right now)
In any case, you can easily find out where your form values are submitted by looking at your console/log output. All the params for each requests are dumped there.
The form fields will be inside the params like params[:form_object][:email] - each field that is submitted has an entry corresponding to the field name.
The params hash not contain all the original values from your #form_object. There will be only those values that you included in the form.
If you need to pass non-editable values to the controller with your form, use hidden_field(s) These will be submitted with the form, but are not visible to the user.

Resources