Replies: 6 comments
-
@Xosmond Can you give a full example of what you mean? My guess would be that you add a method to the objects that returns the action you want. For example: class Author < User
def route
Author::Show.with(self)
end
end
class Admin < User
def route
Admin::Show.with(self)
end
end
link to: user.route # Uses the right action depending on the whether the user is an Admin or an Author Does that help? |
Beta Was this translation helpful? Give feedback.
-
Yes, that helps but how to make it a default behavior?, because I think that would be a method on every class. class Authors::Show < BrowserAction
action do
render user: AuthorQuery.new.find(id)
end
end
class Author
def route
(self.class.name.pluralize.contantize)::Show.with(self).path
end
end But |
Beta Was this translation helpful? Give feedback.
-
@Xosmond That can't be done at runtime, but it can be done at compile time: # https://play.crystal-lang.org/#/r/33sm
class Users::Show
def self.with(id)
# generate a route
end
end
# Probably put it in `src/models/mixins/routeable.cr
module Routeable
macro included
# https://crystal-lang.org/docs/syntax_and_semantics/macros.html
def route
{{ "#{@type.name}s".id }}::Show.with(self)
end
end
end
class User
include Routeable
end
User.new.route I think that should work. This is something that could be added to Lucky for all models, but before I do, can you explain what the full use case is? Preferably with a bit of code from your app? I'd like to see if there is some other way of doing this that's better or if this is the best approach. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Thanks for your help. I trying to move an rails app to crystal with lucky framework and I have a basic case of notifications that I use to redirect the user to action object. On the view for each notification: <li class="notif-info" data-id="<%= notification.id %>" style="cursor: pointer;" onclick="window.location='<%= url_for(notification.notifiable) %>';">
<div class="dropdown-messages-box">
<div class="media-body">
<%= notification.message %>. <br/>
<small class="text-navy"><%= notification.created_at.strftime("%l:%M %p %d/%m/%y") %></small>
</div>
</div>
</li>
<li class="divider"></li> The notification model in ruby: # notification.rb
class Notification < ApplicationRecord
belongs_to :recipient, class_name: "User"
belongs_to :actor, class_name: "User", optional: true
belongs_to :notifiable, polymorphic: true
scope :unread, ->{ where(read_at: nil) }
end
By now I just was trying to have the base view: # src/pages/main_layout.cr
...
def render_notification(notification)
li class:"notif-info", data-id: notification.id.to_s, style:"cursor: pointer;", onclick:"window.location='#{notification.notifiable.route.path}';" do
div class:"dropdown-messages-box" do
div class: "media-body" do
notification.message
br
small class: "text-navy" do
notification.created_at.to_s("%l:%M %p %d/%m/%y")
end
end
end
end
li class: "divider"
end But with your code, could be: # src/models/mixins/routeable.cr
module Routeable
macro included
def route
{{ "#{@type.name}s".id }}::Show.with(self)
end
end
end # src/models/base_model.cr
abstract class BaseModel < LuckyRecord::Model
include Routeable
end The notification model: # notification.cr
class Notification < BaseModel
belongs_to recipient : User
belongs_to actor : User
belongs_to notifiable : BaseModel, polymorphic: true # Here I have the real problem
end Query class: class NotificationQuery < Notification::BaseQuery
def unread
read_at(nil)
end
end The only problem with route would be the pluralization, in this case we are only adding an "s", but compilation would raise an error if there is a problem. Now the polymorphic option is the real thing, (This issue would go on lucky/record repo). How to get the class, because we can't on compilation time, it depends of the class instance. |
Beta Was this translation helpful? Give feedback.
-
@Xosmond pluralization is now present in LuckySupport::Inflector https://github.com/luckyframework/support Looks like Constantize isn't possible in crystal currently but looks like you might have the start of a nice workaround. I wonder if there's a intermediary routing table approach for predefining and referencing routes without the need to know the full scope of the action. |
Beta Was this translation helpful? Give feedback.
-
@Xosmond That is a really nice example. I think the route stuff is handled with the snippet I gave you, but the associations stuff is a bit trickier. I'd like to handle table :notifications do
field notifiable_type : String
field notifiable_id : Int32
end
def notifiable : Comment | SomeOtherNotifiable
case notifiable_type
when "comment"
CommentQuery.new.find(notifiable_id)
end
end
# And in forms you'd do this
NotificationForm.new(notifiable_type: "comment", notifiable_id: comment.id).save This is less than ideal, but I think it will work as a stop-gap solution. Let me know what you think and if it works :) |
Beta Was this translation helpful? Give feedback.
-
What should people do when need to generate a url base on a object?
On rails I use
url_for(object)
, but in lucky i can't useController::Action.with(object)
, because I don't know which action or controller it would be.Is there any way now to solve this? Or maybe should I go to checkout Active record to see how its implemented?
Beta Was this translation helpful? Give feedback.
All reactions