Trying to output the columns for a collection of Models - ruby-on-rails

My controller:
def testing
#models = [User, Products]
end
testing.html.erb:
<% #models.each do |m| %>
<%= render partial: "details", model: m %>
<% end %>
_details.html.erb:
<% #m.columns.each do |c| %>
<li><%= c.name %></li>
<% end %>
I am getting the error:
undefined method `columns' for nil:NilClass
I'm not sure why this doesn't works.
My code worked fine when I was using a single Active Record Model, now I want to be able to do the same thing with an Array of Models, so I broke my template out into a partial so I can loop through my models and output this information.
What seems to be the problem?
Update
Strange because this works fine:
<% #models.each do |m| %>
<%= m.columns %>
<% end %>

You are passing local variable model to your _detail view partial and calling instance variable #m. Change your code in the testing.html.erb to
<% #models.each do |m| %>
<%= render partial: "details", locals: { model: m } %>
<% end %>
and _details.html.erb to
<% model.columns.each do |c| %>
...

Try this:
<% #models.each do |m| %>
<%= render partial: "details", locals: {model: m} %>
<% end %>
And in the _details.html.erb:
<% model.columns.each do |c| %>
<li><%= c.name %></li>
<% end %>

Related

how to render multiple js.erb files in same method in rails?

def react
#postsAlPHA = #user.find(params[:liked_post]).page(params[:page])
#postsBETA = #user.find(params[:disliked_post]).page(params[:page])
end
so I am trying to make #postsAlPHA to render alpha.js.erb for pagination
and #postsBETA to render
BETA.js.erb
<% #postsAlPHA.each do |x| %>
<% x.body %>
<% end %>
<%= paginate #postsAlPHA %>
<% #postsBETA.each do |u| %>
<% x.content %>
<% end %>
<%= paginate #postsBETA %>
Turn them into partials, then render them in your view. Make sure to prefix the filenames with _ e.g. _alpha.js.erb.
In your view:
<%= render partial: 'path/to/alpha.js.erb' %>
<%= render partial: 'path/to/beta.js.erb' %>

rails referencing arrays created by the group_by function

This code causes ActionController to return undefined method `name' for # How do I print the category name
<h2>Categories</h2>
<%= #categories.group_by(&:parent_id).each do |category| %>
<%= category.name %>
<% end %>
I mean, that the :parent_id is an attribute of Category model and #categories is a collection of ::ActiveRecord_Relation class. Let you try:
<h2>Categories</h2>
<%= #categories.group(:parent_id).each do |category| %>
<%= category.name %>
<% end %>
Consider using <%= debug #categories.group_by(&:parent_id) %> so that you can inspect the data structure
I believe you want to pass two arguments to the each block, one for the parent and one for the categories associated with it
<h2>Categories</h2>
<% #categories.group_by(:parent).each do |parent, categories| %>
<%= parent.name %>
<ul>
<% categories.sort_by(&:name).each do |category| %>
<li><%= category.name %></li>
<% end %>
</ul>
<% end %>
Above is based on my assumptions about your data model which could be totally incorrect?

How do I check CanCan abilities on an object in a `shared/partial`?

Per the CanCan documentation, to check if a user has the ability to do something to any element in the view, you do something like this:
<% if can? :create, #project %>
<%= link_to "New Project", new_project_path %>
<% end %>
Or you can check with the class like:
<% if can? :create, Project %>
<%= link_to "New Project", new_project_path %>
<% end %>
In my case, I have a DashboardController#Index, that has this:
#nodes = current_user.nodes.where(:is_comment => nil)
In my views/dashboard/index.html.erb, I have this:
<% #nodes.each do |node| %>
<!-- Upload Video Comment Popup -->
<div class="box">
<%= render partial: "shared/comments", locals: {node: node} %>
</div>
<% end %> <!-- node -->
Then in my shared/_comments.html.erb, I have this:
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, Comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
That doesn't work.
I also tried this:
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
And that doesn't work either.
This is my ability.rb
can :manage, Comment, user_id: user.id
I thought about creating a #comments instance variable in the controller, but the issue with that is that the comments are on a collection of nodes (i.e. I need to show multiple nodes, and each node has multiple comments).
How do I approach this?
Your last code should work after updating to CanCanCommunity version of cancan
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
related to How do I show an error for unauthorized can can access

Rails element if first time appearance

I have a model Post with :mark, :text
I have a list with my post
<% #posts.each do |p| %>
# todo
<% if p.mark? %>
<%= p.mark %> <%= sweet_thing(p.text) %>
<% else %>
<%= sweet_thing(p.text) %>
<% end %>
<% end %>
I need to show p.mark name instead #todo where p.mark first time appearance.
Final txt example:
Audi
Audi, text-text-text-text.
Audi, text-text-text-text.
Audi, text-text-text-text.
Ford
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
UPDATE
My txt render in controller
def txt_receiver
#posts = Post.where("created_at >= ?", 7.days.ago.utc).find(:all, order: "mark, LOWER(post)")
render "txt_for_newspapper", formats: ["text"]
end
An obvious solution is to keep track of seen marks.
<% seen_marks = {} %>
<% #posts.each do |p| %>
<% unless seen_marks[p.mark] %>
<%= p.mark %>
<% seen_marks[p.mark] = true %>
<% end %>
# rest of your code
<% end %>
A better solution (I think) involves grouping posts by their mark and then outputting in groups. But I'm not sure whether it will match your logic regarding missing marks.
<% #posts.group_by(&:mark).each do |mark, posts| %>
<%= mark %>
<% posts.each do |p| %>
<%= p.mark if mark %> <%= sweet_thing(p.text) %>
<% end %>
<% end %>

How to show parent and child in view with will paginate?

I'm having trouble showing my view correctly. I have this as my code right now:
<% for store in #stores %>
<% store.name %>
<% #stores.products.each do |p| %>
<% p.name %>
<% end %>
<% end %>
def index
#stores = Store.paginate(:page => params[:page], :per_page => 20)
end
But end up with the error:
undefined method `products'
I'm trying to show a store and then all of its products, repeating this on the same page as much as possible e.g:
Store1
Product1
Product2
Store2
Product1
Product2
Product3
Product4
How can I do this?
Instead of <% #stores.products.each do |p| %> I think you mean <% store.products.each do |p| %>:
Also, do you not mean to have <%= on the store.name and p.name lines?
<% for store in #stores %>
<%= store.name %>
<% store.products.each do |p| %>
<%= p.name %>
<% end %>
<% end %>
Shouldn't that be store.products inside the loop, where you're accessing store?
<% for store in #stores %>
<%= store.name %>
<% store.products.each do |p| %>
<%= p.name %>
<% end %>
<% end %>
And = is added to the output lines. <%=

Resources