How to use "impressionist" gem in Rails? - ruby-on-rails

I am new to rails dev and is looking to use https://github.com/charlotte-ruby/impressionist but not able to figure out how to use it looking at its documentation. I have done the migration and when trying to put
class ArticlesController < InheritedResources::Base
impressionist
end
OR
class ArticlesController < InheritedResources::Base
impressionist :actions=>[:show,:index]
end
it is throwing no method found error. I am unsure which code needs to be put in model, which to be in controller and which to be in views to see view_count, any help ?

the first question was a type
and as for your second question (inside the comment) the easiest but very efficient way would be
in the view:
<% #pages.each do |page| %>
<%= page.impressionist_count %>
<% end %>

You can also use Impression as a model to query stuff, just like normal models. For example,
Impression.where(user_id: 12).length
I find this is handy if you need some advanced queries.

The documentation does not specify to re-start server. This is not obvious as it does not apply to all gems, however it is required for impressionist.

Related

ApplicationHelper not loaded in Rails 4 engine

Long time reader of SO here. I'm working on a Rails Engine. The big picture problem is that I get a NoMethodError on a helper method living in my Engine's ApplicationHelper. This is for work so I'm going to call the engine Blorge.
I have my helper method that is causing issues anywhere it is called. The Helper method is returning a NoMethodError. I thought maybe I needed to manually add helper Blorge::ApplicationHelper to Blorge::ApplicationController but the issue is still happening.
Am I missing something fundamental about Engines here?
Here is some actual code to give you a better idea of what I'm looking at.
index_header partial
app/views/blorge/shared/_index_header.html.erb
# require_locals is the helper method in question here
<% require_locals ['title'], local_assigns %>
<% title = title.pluralize %>
<section class="main_content-header">
<div class="main_content-header-wrapper">
<%= content_tag :h1, title %>
<div class="main_content-header-save">
<%= link_to "New #{title.singularize}", #new_path, class: "add-button" %>
</div>
</div>
</section>
Pages#home view
app/views/blorge/pages/home.html.erb
<%= render 'blorge/shared/index_header', title: "Welcome, #{current_user.full_name}" %>
...
Engine Application Helper
app/helpers/blorge/application_helper.rb
module Blorge
module ApplicationHelper
def require_locals(local_array, local_assigns)
local_array.each do |loc|
raise "#{loc} is a required local, please define it when you render this partial" unless local_assigns[loc.to_sym].present?
end
end
end
end
Engine Pages Controller
app/controller/blorge/pages_controller.rb
module Blorge
class PagesController < ApplicationController
def home
end
end
end
Engine Application Controller
app/controllers/blorge/application_controller.rb
class Blorge::ApplicationController < ActionController::Base
helper Blorge::ApplicationHelper
...
end
If I restart the server and reload the page, it will usually work just fine, and once it works, the issue doesn't come back for a couple days. After reading Helpers in Rails engine and Rails Engines: Helpers only are reloaded when restarting the server it sounds like I need to include the helper in my application controller with the to_prepare method in my engine.rb file. I am going to try this next but I most want to know if I'm missing something very basic here, If i do just have to add it to engine.rb, can someone explain why?
This might have been too much information, but I'd rather give more than not enough. Thanks in advance.
Edit
the fix seems to have been adding the helpers to application controller within engine.rb. I suspected this would be the fix, but I still have no clue why this is. Does anyone know why I should have to do this?
The Solution
config.to_prepare do
ApplicationController.helper(MyEngineHelper)
end

How do I initialize or show a nested form in rails?

I follow the complex nested forms in railscast and I made it work, a few tweaks here and there. But question is, how do I automatically load a nested form without using the controller?
def new
#model = Model.new
#model.child.build
end
many thanks!
how do I automatically load a nested form without using the
controller?
The simple (incorrect) answer is to include a Partial which will define the ActiveRecord objects as above, like this:
#app/views/controllers/_your_partial.html.erb
<% model = Model.new %>
<% mode.child.build %>
<%= form_for model do |f| %>
...
The problem with this is that it goes against the MVC programming pattern, which is the equivalent of God in the Rails world
--
MVC
Your question is rather peculiar, as it goes against one of the core elements of Rails:
This means every request you make to your Rails application (through the URL) will have to be catered for by a controller action. The role of the controller is to configure / collect the data required to run the app, and then populate the view for the user.
When you want to "call the form without a controller", you're basically saying you want to go against these conventions. Unless you create a gem (which will allow you to extrapolate the ActiveRecord definition code outside of your controller), you'll have to use the controller.
There is a trick though...
--
Class Method
You'll be able to take the functionality you're using in your controller & create a class method to handle it:
#app/models/model.rb
Class Model < ActiveRecord::Base
def self.build
model = self.new
model.child.build
model
end
end
This will allow you to call the following from your controller / partial:
#model = Model.build #-> instead of Model.new :)
module ApplicationHelper
def setup_person(person)
returning(person) do |p|
p.children.build if p.children.empty?
end
end
end
I found this on Ryan Daigle's site but I realize this is a bit outdated. I tried this but I get a returning is not defined or not a method.

How do rails extract an id from an instance variable?

I'm reading "Rails Routing from the Outside In" on RailsGuides.
In Section 1.2, it says
<%= link_to 'Patient Record', patient_path(#patient) %>
will generate the path /patients/17.
What I'd like to know is how rails extract the id from the instance variable.
I've been trying to find the corresponding line of the code on GitHub but can't find.
The ID comes from calling #to_param on the object. Here is a little documentation about it, http://guides.rubyonrails.org/active_support_core_extensions.html#to-param
It calls a to_param method which by default will produce the ID. You can override it to produce nice URLs like this
class Post < ActiveRecord::Base
def to_param
"#{id}-#{title}"
end
end
method responsible is to_param. link to line on
github

Need help integrating youtube_it into my rails app

I am pretty new to rails so this may be an easy question, but I was looking to create a Rails app that would use youtube in it. I have found that youtube_it seems to be the gem of choice for a task like this but I am having trouble using it. Basically, I want to use the gem so that I can get videos from specific users, i.e. Stanford University and create a list of those videos with links to another page that has the video information and player. To test this out I tried the follow code:
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :yt_client
private
def yt_client
#yt_client ||= YouTubeIt::Client.new(:dev_key => dev_key)
end
end
home_controller.rb
class HomeController < ApplicationController
def index
#playlists = yt_client.playlists('stanforduniversity')
end
end
index.html.erb
<h3>Home</h3>
<% #playlists.each do |playlist| %>
<p>Playlist: <%= playlist %></p>
<% end %>
The problem with this is all I get for output on my home page is a list of something like this: #
My questions then are: is there a way to change this output into an actual title? Am I doing something wrong/forgetting a step? Or should I just use python code to use the Google API and put all the videos into my database(I already have some code for this) and just access it using my rails app?
Hope this is clear enough.
it looks like what you want to print out is the name of the playlist - but that is an attribute of the playlist object, so you'll need something like:
<% #playlists.each do |playlist| %>
<p>Playlist: <%= playlist.title %></p>
<% end %>
otherwise ruby is trying to "print" the playlist object - which just doesn't work the way you expect.
Note: I've not used this gem either, I'm gathering this info from the gem docs here: https://github.com/kylejginavan/youtube_it
https://github.com/kylejginavan/youtube_it or youtube_it is the new version of youtube_g. This was forked and enhanced. If you need any enhancements please reach out to me.
you have a complete demo that I made here
http://youtube-it.heroku.com/
included source!

What is the best way to avoid code duplication between views and controllers in Ruby on Rails?

I currently have code in my ApplicationController to check if a user is logged in and has the required access to perform a given action (the tests take place in a before_filter).
I require the same functionality in the views to decide if I should be showing the admin links in a list view, but how do I best avoid duplicating code in the controllers and views?
The way I have chosen to do it now, is to have the user_can_edit_customers? essentially be a wrapper for 'can_edit_customers?' on my User class:
ApplicationController:
class ApplicationController
And then do something similar in my view helpers.
This way all functionality is encapsulated in the User model but I still need to define wrappers in my controllers and helpers, but are there smarter ways of doing this?
Note, the user stuff is only an example - this also applies to other pieces of functionality.
I would say do away with the wrappers and just call can_edit_customers? directly on the user object passed to the view.
If you want to keep them a solution might be to use helper_method in your controller.
helper_method :current_user, :can_edit_customers?
def current_user
#current_user ||= User.find_by_id(session[:user])
end
def can_edit_customers?
#current_user.can_edit_customers?
end
This way the method also becomes available in the view.
<% if can_edit_customers? -%>...<% end -%>
Just to be more direct. The helper_method "macro" in a controller causes a controller method to behave as if it's also a method in the application helper.
helper_method :current_user, :can_edit_customers?
Personally I think you should not use helpers.
I would take a different solution.
Let's say that we have Cucumber, a model, that should not be editable by some users. I create #editable? method as follows:
class Cucumber < ActiveRecord::Base
def editable?(current_user)
# Something happens here.
end
end
Note that if a page is accessible by everyone, current_user might be false.
Then, in the views you're able to do:
<%- if #cucumber.editable?(current_user) -%>
<%# Something happens here. -%>
<%- end -%>
And, in the controllers, use a filter.
The best thing about this approach is that it follows Fat Model, and enables you to easily cover your permissions with unit tests.
I think helpers are the way to do what you want. As for checking in views whether the user has or not the priviledge to do something, you could put a flag in your session data (e.g. session[:admin] = true and check that in your view.
It is common practice to make methods like logged_in? available in the controller and the views. For most cases, you don't need to push down authorization logic into the models.
Definetly go with with the approach user Hates described. Have a look at plugins like restful_authentication and acts_as_authenticated, to see how they did it.
There are several railscasts (http://railscasts.com/episodes?search=authentication) covering this topic. For instance, you could write a helper that takes a block and is then used like this:
<%- admin_user_ do %>
<%= link_to .. %>
<%= link_to .. %>
<%= link_to .. %>
<%- end %>

Resources