Reputation: 503
I am fairly new to RoR. I have spent the afternoon reading about modules (used as concerns). I have yet to find a good article which describes the file path that using include
or extend
methods looks up (if include
and extend
are methods?).
The most specific example I have found was here: Ruby On Rails - Using concerns in controllers. This makes me feel that if I wanted to include the 'Bar' module in my Foo
model I would create a concerns/
directory in my models/
directory, and create a 'Bar' module file in this folder.
# in models/concerns/bar.rb
modlue Bar
# do I need this???
extend ActiveSupport::Concern
def speak_bar
puts "model module bar!"
end
end
# in models/foo.rb
class Foo < ApplicationRecord
include Bar
end
# I could then perform:
Foo.new.speak_bar
=> "model module bar!"
And if I wanted to include a Bar module in my Foo controller I would do:
# in controllers/concerns/bar.rb
modlue Bar
# Again, do I need this???
extend ActiveSupport::Concern
def speak_bar
return "controller module bar!"
end
end
# in controllers/foo.rb
class FoosController < ApplicationController
include Bar
def make_bar
@bar = speak_bar
end
end
# I could then use @bar in my views (anywhere else?) as <%= @bar %> and get it to output
=> "controller module bar!"
Summary of questions:
Is this understanding set out above correct in terms of the file paths?
And do I need to use the extend ActiveSupport::Concern
line in order to use this path system?
Are include
and extend
methods?
Thank you for your help.
Upvotes: 1
Views: 2354
Reputation: 1959
You should always extend your concerns module with the supplied concerns base from Rails.
Pathing is usually app/models/concerns/file.rb
for model concerns and app/controllers/concerns/file.rb
for controllers and so on.
If you specifically have logic that crosses the controller and models separation, consider placing that in lib
, and adding lib to your autoload path.
include
and extend
are methods. Most things (almost all) are objects in ruby. So almost all operations are methods on objects.
Upvotes: 4
Reputation: 355
concerns
are auto-loaded by rails by default starting from rails v4+
. You can read the article written by DHH to get a fair idea of what concern does and what does it try to solve.
However, it gets pretty complicated in determining which scope
you are in and what self
is in the method. Check out this video by Ryan Bates regarding the problems with concerns
.
To solve some parts of the problem, I generally nest the concern inside a folder and refer it by giving a class
. For example
# app/models/concerns/user/authentication.rb
class User
module Authentication
extend ActiveSupport::Concern
# stuff
end
end
and include in the model
like
# app/models/user.rb
include Authentication
In my opinion, the separation of concerns helps in isolating your methods. For example, you can create a Filterable
concern
in a similar way, and isolate it from your other models
.
Upvotes: 2
Reputation: 15838
the file path that using include or extend
Rails does some magic when starting to autoload a lot of things so you don't have to worry later when you call "Bar". This talk is really helpfull to understand WHY you can just do include Bar
inside a rails model without much thinking https://www.youtube.com/watch?v=I0a5zv7uBHw
Usually, you want model related concerns inside /app/models/concerns and controller related concerns inside /app/controllers/concerns, but that's just for organization purposes, rails will autoload them even if you use /app/whatever/concerns, so be carefull about name collisions.
You DO need to extend ActiveSupport::Concern
if you want to use the syntax sugar that Concerns provide, but at the end they are just modules that can be included. https://api.rubyonrails.org/classes/ActiveSupport/Concern.html check this examples, concerns are just a way to write modules to share behaviour with a more friendly syntax for common rails patterns.
extend
is a method of Object https://docs.ruby-lang.org/en/2.6.0/Object.html#method-i-extend
include
is a method of Module https://docs.ruby-lang.org/en/2.6.0/Module.html#method-i-include (and Module inherits extend
from Object)
Upvotes: 2