Rails: Rendering a Superclass Partial - ruby-on-rails

I have two classes (Impressions and Replies) which inherit from the parent class Comment:
class CommentsController < ApplicationController
. . . .
end
class ImpressionsController < CommentsController
. . . .
end
class RepliesController < CommentsController
. . . .
end
In my view, I want them to render the same way. Right now, I'm approaching it like this:
<%= render #comment %>
Ideally, this would render the partial "/comments/_comment", but instead Rails want to render things like "/impressions/_impression" or "/replies/_replies." Is there any way to strong arm Rails into do "/comments/_comment"?

With :collection you can render a collection of objects. Given a single object you should us :object instead.
<%= render partial: '/comments/comment', object: #impression %>
The :as is not necessary as long as the partial is named 'comment'. If you name your partial e.g. 'my_comment' then #impression would be accessible via the local variable 'my_comment' and you would have to use :as to define a different local name.
However in your case I would prefer to define a partial path for the Impression and Replies model as follows (Rails >3.2.?):
class Impression < ActiveRecord::Base
...
def to_partial_path
"comments/comment"
end
end
Then you can use the standard rendering with an object or collection
<%= render #comment %>

I think smth like this can help:
<%= render :partial => '/comments/comment', :collection => #impressions,
:as => :comment %>

Related

Accessing controller data in order to pass local variables for rendering a haml partial in a view

I am trying to render a partial within a view. I have the following code in my view which calls upon the haml document being rendered:
= render :partial => 'data_popups/events'
However I need to pass local variables so 'undefined local variable' is solved. The controller, which contains all of the data, is under dataPopupsController#events ... is there anyway to access the data so I can pass local variables to the partial? Any and all help is welcome. Cheers~
As long as the data is available in your outer view, you can pass it to a partial using the locals option. For instance, if this was on your home page, you could pass the data to the controller like this...
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
def home
#data = Model.get_data
end
end
Then, in your view, pass that #data into your partial using the locals option of the render method:
# app/views/pages/home.html.erb
<%= render :partial => 'data_popups/events', :locals => { :data => #data } %>
Without seeing your controller code, here's a basic example of what you could do:
class UsersController < ApplicationController
def index
#data = User.get_data
end
end
# views/users/index.html.erb
<%= #data.some_method %>
<%= render 'data_popups/events', :locals => { :data => #data } %>
# views/data_popups/_events.html.erb
<%= data.some_other_method %>
Notice that when you pass #data as a local to 'data_popups/events', you now reference the local variable as data.

Use the same partials for two controllers in two different folders

I have two controllers like this:
app/controllers/collection_controller.rb:
class CollectionController < ApplicationController
def create
#collection = Collection.new(name: params[:name])
#collection.save!
render #collection
end
end
And an inherited class:
app/controllers/enterprise/collection_controller.rb:
class Enterprise::CollectionController < ::CollectionController
def create
#collection = Collection.new(name: params[:name])
#collection.company = Company.find(params[:company])
#collection.save!
render #collection
end
end
I have two partials:
app/view/collections/_collection.json.jbuilder:
json.extract! collection, :title, :description
json.users do
json.partial! collection.user
end
app/view/collections/_user.json.jbuilder:
json.extract! user, :name, :surname
The problem is:
When I load Enterprise::CollectionController#create, I get missing template app/views/enterprise/collections/_collection ....
I want Enterprise::CollectionController to use app/view/collections/_collection.json.jbuilder instead of app/view/enterprise/collections/_collection.json.jbuilder.
I tried to do something like:
render #collection, partial: 'collections/collection', but I receive:
But I receive:
missing template for ... app/views/enterprise/users/_user ...
How can I solve this?
After you changed your render partial to
render #collection, partial: 'collections/collection'
you are not getting an error for collection partial. you are getting an error for user partial. You will have to change the way you are rendering user partial to
json.partial! "collections/user", user: collection.user
Update:
you can try append_view_path. So basically you will append to the default search locations
class Enterprise::CollectionController < ::CollectionController
before_filter :append_view_paths
def append_view_paths
append_view_path "app/views/collections"
end
end
So rails will search in app/views/enterprise/collections, app/views/shared, app/views/collections in order
You can also use prepend_view_path if you want rails to search in app/views/collections first
PS: I haven't tested this.

undefined method `_path' in form, with routes defined at :resources

I've been stuck on this for a bit and can't figure out the exact reason why I'm getting the following error:
undefined method `entries_path' for <%= form_for(#entry) do |f| %>
entry_controller:
class EntryController < ApplicationController
def index
end
def new
#entry = Entry.new
end
def create
#entry = Entry.new(user_params)
if #entry.save
redirect_to #entry
else
render 'new'
end
end
private
def user_params
params.require(:entry).permit(:comment, :flag)
end
end
routes has:
resources :entry
and the new page where the error occurs:
<%= form_for(#entry) do |f| %>
<%= f.label :comment %>
<%= f.text_field :comment %>
<%= f.label :flag %>
<%= f.text_field :flag %>
<% end %>
I can't figure out why I'm getting this error.
form_for needs to reference the path associated with #entry (i.e. entries_path), but your routes.rb file uses the singular form of the resource (:entry) rather than the required plural form (:entries), so the proper path names don't exist.
Rails models use the singular form, but the Rails database, controllers, views use the plural form and this is reflected in the routes file. One way to remember this is that a model is describing a single class that each object belongs to. Everything else, pretty much, is responsible for managing multiple instances, so while they themselves are singular (e.g. Controller), they refer to the objects they manage in the plural form (e.g. EntriesController, controller/entries directory).
See Ruby on Rails plural (controller) and singular (model) convention - explanation for more discussion of this.
Controller and views should always be treated in plural form. For example, if you have an object Book, then the controller declaration should be
class BooksController < ApplicationController
and the views( new, edit, show, index ) should be inside a folder named
/books
Also, the declaration of routes should be in plural form. In this case, the routes should be declared as
resources :books
You could try to generate the controller and view folder by running in your terminal:
rails generate controller name_of_object_in_plural_form( for sample, books)
The script will generate a controller named books_controller.rb and /books folder under /views

Namespaces route and model path rails

I'm just started with rails and until now I was very happy with it, but there is one thing I can't figure out.
I have some ActiveRecords models in a namespace "Monitor", and I have some controllers in a Namespace "Settings". What I want to accomplish is that I can use the namespaced models in my settings controllers/forms.
I've got this:
/config/routes.rb
namespace :settings do
resources :queues, :channels
end
/app/controllers/settings/queus_controller.rb
class Settings::QueuesController < ApplicationController
def new
#queue = Monitor::Queue.new()
render 'form', :layout => false
end
def create
#queue = Monitor::Queue.new(post_params)
if (#queue.save)
#status = 'added'
render 'success'
else
render 'form', :layout => false
end
end
def edit
#queue = Monitor::Queue.find(params[:id])
render 'form', :layout => false
end
...
end
/app/models/monitor/queue.rb
module Monitor
class Queue < ActiveRecord::Base
end
end
/app/views/settings/form.html.erb
<%= form_for #queue do |f| %>
...
<% end %>
Now Rails is complaining about a missing method : monitor_queues_path or Rails generates a path like /monitor/queues instead of /settings/queues(:new/edit).
What am I missing here?
Aah I found it!
This post gave me the proper solution:
Rails namescoped model object without module prefix route path
The problem came from the prefix from the ActiveRecord class:
module Monitor
class Queue < ActiveRecord::Base
end
end
This should be
module Monitor
class Queue < ActiveRecord::Base
def self.model_name
ActiveModel::Name.new("Monitor::Queue", nil, "Queue")
end
end
end
After changing this I only needed to change the form_for in the correct way:
<%= form_for [:settings, #queue] do |f| %>
And that fixes it :D
You are using nesting for your Queue models. Therefore your form_for call needs to know about the parent model too. So in your case you nested Queue under Setting so you will need to provide a setting object as well. I'm guessing in your controller you made a #setting variable. If this is the case then the following code will work for you.
<%= form_for [#setting, #queue] do |f| %>
<%# Your form code here -%>
<% end -%>
I found a solution from my friend #mkhairi he said to use this on the parent model :
class YourParentModel < ApplicationRecord
def self.use_relative_model_naming?
true
end
end
then you can use back ur lovely short path.
Source :
https://coderwall.com/p/heed_q/rails-routing-and-namespaced-models

Using View page, Controller and Helper

I am new in Rails. And I have a project that;
I should get a value from user in View page (for example index), and I should use the value in Helper then send the result of Helper to Controller and show the result in a new View page (for example details). Additionally I have to save results to database. Right now I have helper, controller and view pages but I can't connect these three part to each other. I need help
Controller;
def index
#user = Mpeople.new[:user]
redirect_to "secondstep"
end
def secondstep
# helper should have controled here
redirect_to "following"
end
def following
#user = Mpeople.all
end
Model;
class Mpeople < ActiveRecord::Base
has_one :username
accepts_nested_attributes_for :username
end
View;
<% form_for :user, :url => {:action => "index"} do |pform| %>
<% pform.fields_for :person do |namefield| %>
Twitter Name : <%= namefield.text_field :username %>
<%= button_to "OK", :action => "following" %>
<% end %>
<% end %>
And helper is more longer, it sends twitter name to twitter and get following of a user from api.twitter.com
This is some of my helper; I edit it after your comment but I am not sure if it is correct or not.
module FafHelper
class PeopleController
require 'people_helper'
# txtname = indexteki textbox'un adına eşitle
#txtname = tname
txtname = namefiled.text_field
.....
a_get("1/users/lookup.#{json}").
with(:query => {:screen_name => txtname, :user_id => id_list}).
end
end
..
You no need to connect views and helper as by default all the helper modules are included in the views.
And do include the helper in you controller. Helper is a module and controller is a class. Just include the module in the class.
To get the clear picture please post exactly your structure.

Resources