-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
session
, cookies
, and current_user
are only accessible while rendering
#52
Comments
Howdy, @ernest4 ! If I understand correctly, you do not need to un-comment that section in the initializer. You would only need to do that if you wanted to do something different than what is already there. The session and cookies are available as instance methods ( If you want to use the user from there, you need to set it yourself. I suspect adding something like this to your component will give you what you want: around_action :with_current_user
private
def with_current_user(&block)
Current.set(user: current_user, &block)
end |
Sorry I'm still stuck :D So I've commented out the motion config again. And I'm trying to access the cookies and session in the component. This is the component: module Account
class LocalizationComponent < SvComponent
include Motion::Component
around_action :with_current_user
def initialize
@setting = Account::AccountComponent::ACCOUNT_SETTINGS.find do |setting|
setting[:title] == 'Localization'
end
end
map_motion :update_language
def with_current_user(&block)
debugger
# Current.set(user: current_user, &block)
end
def update_language(event)
# TODO: ...
# Any of these puts will fail
# puts current_user
# puts session
# puts cookies
debugger
# doest work, no cookies or session ...
# Current.user.update(:language => event.target.value)
end
def call
div(:class => 'sv-container lg:w-2/3 mx-auto') do
c div(:class => 'pt-4')
c div(:class => 'sv-card w-full') {
c span(t(@setting[:title]), :class => 'sv-text text-xl sv-text-bold')
c div(:class => 'pt-2')
c span(t(@setting[:subtitle]), :class => 'sv-text')
}
c div(:class => 'pt-4')
c div(:class => 'sv-card') {
c label(:user, :language, t('Language'), :class => 'sv-text')
c div(:class => 'pt-2')
c select(:user, :language, Localized::SUPPORTED_LANGUAGES.map { |lang| [lang, lang]},
{ :selected => Current.user.language },
{ :class => 'sv-input', :data => { :motion => 'update_language' } })
# {:class => 'sv-input', :data => { :motion => 'change->update_language' }})
}
end
end
end
end so at the two byebug points there im trying to access cookies or session but i get error? still no sure what i'm doing wrong? btw this is what my connection.rb looks like, does that mean that i should have access to current_user as well (because that errors out too)? # frozen_string_literal: true
module ApplicationCable
# handles incoming connection and authentication
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user_from_cookies
end
private
# TODO: might need to stop using the reject_unauthorized_connection check here as this stops
# socket traffic for non logged in users (when it might be desirable like in case of Motion
# components).
def find_verified_user_from_cookies
current_user = User.find_by(:id => cookies.encrypted[:user_id])
current_user #|| reject_unauthorized_connection
end
end
end I tried calling |
Ok so i got it to work, but just wanna double check if this is the right conventional way to go about this. So I can't access session or cookies in with_current_user or update_language, but those methods can access the instance variables of component. So i just set the instance variable for current_user in initialize, then use that in around_action hook, which then sets it up to be accessible in update_language callback (i could just access @current_user in update_language of course, but i think i'll just extract the around_action logic to SvComponent so i can have consistent access to Current.user, like the rest of the app.) Does that all sound how it should be? You've mentioned that 'The session and cookies are available as instance methods...' and i was looking at the motion code spec a little bit and they test that they are available in the render (i.e. the call method), which seems like they are available there. However I need to access them in the actual component class methods, so not sure if that actually works? module Account
class LocalizationComponent < SvComponent
include Motion::Component
around_action :with_current_user
def initialize
# ...
# TODO: store id only and use that to look up in with_current_user
# as marshaling objects is more memory intensive !!
@current_user = Current.user
end
map_motion :update_language
def with_current_user(&block)
Current.set(:user => @current_user, &block)
end
def update_language(event)
# TODO: error / success handling
Current.user.update(:language => event.target.value)
end
def call
# ...
end |
👍 I don't see any issue with this approach. I think it is a good workaround until I figure something else out for the view context.
This is a really good point. I've yet to run across a situation where I wanted to use them outside of rendering, so I had not noticed. Unfortunately, with how |
session
, cookies
, and current_user
are only accessible whlile rendering
session
, cookies
, and current_user
are only accessible whlile renderingsession
, cookies
, and current_user
are only accessible while rendering
Yeah.. current_user is accessed pretty frequently though for any app with auth. In the controller you normally authenticate the user, then authorise the user to change some resource that only belongs to him/her. With motion, this all happens in the motion callback now, so that's why I need current_user there to authorize the update. I'm basically turning motion components into overpowered 'React like' things :D difference is that while React used to push / pull state to/from Redux (while synchronizing with backend via AJAX JSON) motion components simply, cleanly and directly just update the models in question - and i'm loving it :D |
Hey guys :)
If i understand this correctly then i need to uncomment this to get access to session / cookies?
But no matter what, i cant seem to be able to access them. Get an error about undefined method 'controller'
Am i doing something wrong or?
just trying to execute this bit of logic here, update Current user.
Thanks
The text was updated successfully, but these errors were encountered: