How to write a Rails mixin that spans across model, controller, and view
You could pluginize it (use script/generate plugin).
Then in your init.rb just do something like:
ActiveRecord::Base.send(:include, PluginName::Sendable)
ActionController::Base.send(:include, PluginName::SendableController)
And along with your self.included that should work just fine.
Check out some of the acts_* plugins, it's a pretty common pattern (http://github.com/technoweenie/acts_as_paranoid/tree/master/init.rb, check line 30)
Correct way to optimize repeated Rails code
A simple way is to split the code into modules and use mixin.
A better way is to write your own plugins for your common code.. likeact_as_commentable
you can learn about it here: http://guides.rubyonrails.org/plugins.htmlThe correct way is to do a comments controller, and have it nested to your models, giving a restful routes like this: /mymodelname/1/comments.
An easy way to make such controllers is by using inherited_resources plugin.
scroll down to the "Polymorphic belongs to" section- there is a comments controller example
Access attributes in controller while looping in view
You want to do all the calculation on the server in your controller action before rendering the view.
So in addition to gathering the @deals
, you will also set an instance variable for the count.
def index
@deals = Deals.all # or whatever your finder is
@common_listitem_count = ListItem.where(code: @deals.pluck(:code)).count
end
Then just call the count instance variable in the view:
<%= @common_listitem_count %>
Where should I put this code?
Check out the discussion here.
Refactoring ActiveRecord models with a base class versus a base module
There's a fundamental difference between those two methods that all the other answers are missing, and that's rails' implementation of STIs (Single Table Inheritance):
http://api.rubyonrails.org/classes/ActiveRecord/Base.html (Find the "Single Table Inheritance" section)
Basically, if you refactor your Base class like this:
class Base < ActiveRecord::Base
def foo
puts "foo"
end
end
class A < Base
end
class B < Base
end
Then, you are supposed to have a database table called "bases", with a column called "type", which should have a value of "A" or "B". The columns on this table will be the same across all your models, and if you have a column that belongs to only one of the models, your "bases" table will be denormalized.
Whereas, if you refactor your Base class like this:
Module Base
def foo
puts "foo"
end
end
class A < ActiveRecord::Base
include Base
end
class B < ActiveRecord::Base
include Base
end
Then there will be no table "bases". Instead, there will be a table "as" and a table "bs". If they have the same attributes, the columns will have to be duplicated across both tables, but if there are differences, they won't be denomarlized.
So, if one is preferable over the other, yes, but that's specific to your application. As a rule of thumb, if they have the exact same properties or a big overlap, use STI (1st example), else, use Modules (2nd example).
Rails 7 signup form doesn't show error messages
If you look at the logs you can see that Rails is getting an AJAX request in the form of a turbo stream:
Processing by UsersController#create as TURBO_STREAM
Where it should read:
Processing by UsersController#create as HTML
To disable turbo you want need to set a data-turbo="false"
attribute on the form:
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, data: { turbo: false }) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
The local: false
option only works with the old Rails UJS javascript library which was the default prior to Rails 7. You can also disable Turbo by default with:
import { Turbo } from "@hotwired/turbo-rails"
Turbo.session.drive = false
See:
https://turbo.hotwired.dev/handbook/drive#disabling-turbo-drive-on-specific-links-or-forms
Socket.IO with Ember and Ember-Data
There's a very simple solution to this which I'm using in some of my apps. You can either have a general purpose callback for the socket and accept any kind of data
callback: function(message) {
// this is better than just `eval`
var type = Ember.get(Ember.lookup, message.type);
store.load(type, message.data);
}
or here it is specifically tailored to your use case
socket.on('apartment/new', function(apartment) {
store.load(App.Apartment, apartment);
});
using store.load
will load the record data directly into the identity map. There's also loadMany
for loading multiple records.
Related Topics
Active Admin: Sorting on Multiple Columns
Dynamically Generate Scopes in Rails Models
Why Are Metaclasses Created in Ruby
How to See the Ruby Code in a Proc
Garbage Collector Tuning in Ruby 1.9
Installing Native Ruby Extensions on Windows for Jekyll
Why Doesn't "Case" with "When > 2" Work
Differencebetween 'File.Read' and 'Io.Read'
How to Remove a Non-Breaking Space in Ruby
Stubbing Chained Methods with Rspec