If I'm writing a private method, does rails think that every method under the word private is going to be private? or is it supposed to be only private for the first method?
private
def signed_in_user
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
does that mean signed_in_user and correct_user is private? or just signed_in_user? Does that mean whenever I need to write private methods, it should be at the end of my file now?
Yes, each method after the private keyword will be private. If you want to change back to defining non-private methods, you can use a different keyword, like public or protected.
See Where to place private methods in Ruby?
Yes all the methods under private are private. Usually you will, indeed, find those methods at the bottom of your file.
But you can "stop" this by writing another keyword like protected and then all the methods following would be protected.
Or you can even define your access control in this way too, listing your methods as arguments to the access control functions (public, protected, private):
class SomeClass
def method1
...
end
def method2
...
end
def method3
...
end
# ... more methods def
public :method1, method4
protected :method3
private :method2
end
As others have written, Every method that follows the private keyword immediately is private in Ruby. This is plain Ruby syntax and has nothing to do with rails.
private
.....
def pvt_meth_1
.....
end
def pvt_meth_2
.....
end
public
def pub_meth_1
......
end
It works the same way as c++ private, public tags, so yes both of them will be private
Related
I'm trying to move some business logic out of one of my controllers, StoreController and into a new Store::CreateService service object. Learning about services recently, it doesn't seem to be much of an established pattern for implementing them. I'm running into an error trying to call a protected method. I can obviously move the logic from those protected methods directly into execute but my understanding was that this should be okay to Rails.
undefined local variable or method `find_and_set_account_id' for #<Store::CreateService:0x00007f832f8928f8>
Here is the Service object
module Store
class CreateService < BaseService
def initialize(user, params)
#current_user, #params = user, params.dup
end
def execute
#store = Store.new(params)
#store.creator = current_user
find_and_set_account_id
if #store.save
# Make sure that the user is allowed to use the specified visibility level
#store.members.create(
role: "owner",
user: current_user
)
end
after_create_actions if #store.persisted?
#store
end
end
protected
def after_create_actions
event_service.create_store(#store, current_user)
end
def find_and_set_account_id
loop do
#store.account_id = SecureRandom.random_number(10**7)
break unless Store.where(account_id: account_id).exists?
end
end
end
You have an extra end after def execute..end. That end closes the CreateService class. This means your protected methods are defined on the Store module.
Hence the missing method.
All the articles say about the difference between private and protected methods, however there's no clearance about using it.
So if code something like:
private
def my_method
#some code
end
Does private affect only the my_method or everything below?
UPDATE:
And if affects everything what if I want to use protected methods as well?
If I code below my_method:
protected
def another_method
#some code
end
Does it mean that private method has ended and protected methods section has started?
To simply answer your question: yes, when you have the following code:
private
....
protected
....
Then private stops where protected begins.
I am learning rails and I have a question
How can I call an action from another in the same controller?
def new
new_method()
end
private
def new_method
...
end
This would be the right way?
The parenthesis is optional in Ruby. But, one action receive a call from client and respond one output. Your private "action" is only a function or method.
class User
def create
make_something(params)
end
private
def make_something(params)
#some implementation
end
end
Just started to learn Ruby. I'm confused with Ruby's private keyword.
Let's say I have code like this
private
def greeting
random_response :greeting
end
def farewell
random_response :farewell
end
Does private only applied to the #greeting or both - #greeting and #farewell?
It's fairly standard to put private/protected methods at the bottom of the file. Everything after private will become a private method.
class MyClass
def a_public_method
end
private
def a_private_method
end
def another_private_method
end
protected
def a_protected_method
end
public
def another_public_method
end
end
As you can see in this example, if you really need to you can go back to declaring public methods by using the public keyword.
It can also be easier to see where the scope changes by indenting your private/public methods another level, to see visually that they are grouped under the private section etc.
You also have the option to only declare one-off private methods like this:
class MyClass
def a_public_method
end
def a_private_method
end
def another_private_method
end
private :a_private_method, :another_private_method
end
Using the private module method to declare only single methods as private, but frankly unless you're always doing it right after each method declaration it can be a bit confusing that way to find the private methods. I just prefer to stick them at the bottom :)
In Ruby 2.1 method definitions return their name, so you can call private on the class passing the function definition. You can also pass the method name to private. Anything defined after private without any arguments will be a private method.
This leaves you with three different methods of declaring a private method:
class MyClass
def public_method
end
private def private_method
end
def other_private_method
end
private :other_private_method
private
def third_private_method
end
end
It applies to everything under private i.e greeting and farewell
To make either of them private you can make greeting alone private as below:
def greeting
random_response :greeting
end
private :greeting
def farewell
radnom_response :farewell
end
Documentation is available at Module#private
In Ruby 2.1 you can mark single methods as private also like this (space is optional):
class MyClass
private \
def private_method
'private'
end
private\
def private_method2
'private2'
end
def public_method
p private_method
'public'
end
end
t = MyClass.new
puts t.public_method # will work
puts t.private_method # Error: private method `private_method'
# called for #<MyClass:0x2d57228> (NoMethodError)
If I have a class in Ruby:
class Person
def get_person
end
protected
def check_person_1
end
def check_person_2
end
private
def auth_person_1
end
def auth_person_2
end
end
is auth_person_2 a private function or public or protected function? I mean I do not have the "private" keyword above the function name, but it is under the auth_person_1 function which is however directly under "private", what function type auth_person_2 is in this case? and how about function check_person_2 ?
in this case auth_person1/2 would be private, check_person1/2 would be protected and get_person would be public.
Functions look for the last keyword and that's what they use.
You can also do it this way :
class Person
def method1
end
def method2
end
def method3
end
def method4
end
public :method1, :method4
protected :method2
private :method3
end
Doing something like this would also work :
class Person
def method
end
private
def method1
end
public
def method2
end
end
You can have them in any order and use the same keyword more than once.
Ruby is not like C# where you have to define the encapsulation for each method.
Everything bellow the method "private" is private until you call one of the other methods (private, public or protected). For example, you can use "public" to define a public method after a block of private ones.
By default your class is public.
class Hello
...
end
is the same as
class Hello
public
...
end