Rails 3.1 limit user created objects
Try something like this:
class User < ActiveRecord::Base
has_many :things
end
class Things <ActiveRecord::Base
belongs_to :user
validate :thing_count_within_limit, :on => :create
def thing_count_within_limit
if self.user.things(:reload).count >= 5
errors.add(:base, "Exceeded thing limit")
end
end
end
Edit: updated for Rails 3
RoR 3 Limiting users to 2 posts per day
Try this:
class User
has_many :posts do
def today
where(:created_at => (Time.zone.now.beginning_of_day..Time.zone.now))
end
def this_week
where(:created_at => (Time.zone.now.beginning_of_week..Time.zone.now))
end
end
end
class Post
belongs_to :user
validate :user_quota, :on => :create
private
def user_quota
if user.posts.today.count >= 2
errors.add(:base, "Exceeds daily limit")
elsif user.posts.this_week.count >= 5
errors.add(:base, "Exceeds weekly limit")
end
end
end
Ruby on Rails - Limit a user to a set number of database entries
You could do something like this:
class User < ActiveRecord::Base
has_many :domains
has_many :posts, through: :domains
def post_limit
roles.first.posts.count
end
end
class Domain < ActiveRecord::Base
belongs_to :user
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :domain
delegate :user, to: :domain
validate :posts_count_within_limit, on: :create
def posts_count_within_limit
if self.user.posts(:reload).count >= self.user.post_limit # self is optional
errors.add(:base, 'Exceeded posts limit')
end
end
end
Based on this answer.
Ruby on Rails: Limit user to endorse(comment) 3 other users a month
I actually found a reason.
It should look like this in the user model:
has_many :endorsing, through: :active_endorsements, source: :endorsed do
def this_month
where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now))
end
end
I was missing the do..end at the other post and placed the method at the end of the model. It seems to work now, produces an error
ArgumentError (First argument in form cannot contain nil or be empty):
app/views/shared/_unendorse.html.erb:1:in `_app_views_shared__unendorse_html_erb__1506472371249770260_70025812987440'
app/views/endorsements/create.js.erb:1:in `_app_views_endorsements_create_js_erb__2132303159922640595_70025812908380'
app/controllers/endorsements_controller.rb:8:in `create'
In the server log. I belive thats a valid error (already got 3 endorsed users) - but how can i display it on the website? So it looks like in the method
"Exceeded endorse limit (3) this month"
instead of what the error produces?
Edit:
I've managed to solve the error displaying correctly :)
It boiled down to have this method in my endorsement model:
def endorsement_count_within_limit?
if endorser.endorsing.where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now)).count >= 3
errors.add(:base, "Exceeded endorse limit (3) this month")
end
end
and having my endorse partial that render the correct form depending if user is endorsing other user or not:
<%= form_for(current_user.active_endorsements.build, remote: true) do |f| %>
<% if f.object.endorsement_count_within_limit? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(f.object.errors.count, "error") %>.
</div>
<ul>
<% f.object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% else %>
<div><%= hidden_field_tag :endorsed_id, @user.id %></div>
<%= f.submit "Endorse", class: "btn btn-primary" %>
<%= f.text_field :comment, class: 'form-control' %>
<% end %>
<% end %>
Set has_many or has_one dynamically according to object own attributes
My first thought would be to use single-table inheritance, since Orphan is a specific kind of child with different behaviors.
When deciding whether this is the right route, I found this post really helpful.
If you chose use STI, you'd end up with something like...
class Child < ActiveRecord::Base
end
class Orphan < Child
has_one :parent
end
class StereotypicalFamilyUnit < Child
has_many :parents
end
Rails will also assume and expect that you have a "type" string column in the Child table. When you call Orphan.new, it will create a child of type "Orphan." And if you do "Orphan.first" it's basically doing Child.where(type: "Orphan").first behind the scenes.
Another option (which I eventually opted for in an app I'm building in lieu of STI), would be to have a boolean as you suggested and use scopes, which might look like:
class Child < ActiveRecord::Base
has_many :parents
scope :orphan, -> { where(orphan: true) }
end
Which lets you instead call Child.orphan.new or Child.orphan.first, and do different things in views/controllers when orphan is true. You could then also follow the advice in this prior post to create a custom validation for orphans.
Rails: `includes` a `has_many` relation with `limit`
There is a note tucked away in the associations documentation under "Eager loading of associations":
If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects.
So, it is behaving as documented even though that might not be the intuitive behaviour.
The work around is to not eager load the limited associated and to access separately afterwards. As you point out that's not ideal but it is almost certainly preferable to loading all of the associated objects without a limit.
Related Topics
Using Send_File to Download a File from Amazon S3
Nokogiri, Open-Uri, and Unicode Characters
Why Does Ruby'S 'Gets' Includes the Closing Newline
How to Get Ruby/Homebrew/Rvm to Work on Yosemite
What Are the Magic $-Prefixed Variables in Ruby
Idiomatic Object Creation in Ruby
How to Turn a String into a Method Call
Block Comments in HTML.Erb Templates in Rails
How to Implement a Friendship Model in Rails 3 for a Social Networking Application
How to Create a Class Instance from a String Name in Ruby
How to Set Up the Database.Yml File in Rails
Why Are Symbols in Ruby Not Thought of as a Type of Variable
Confusion With Atomic Grouping - How It Differs from the Grouping in Regular Expression of Ruby
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
Can't Access Rubygems - Possibly Due to Ssl
Is There a 'Variable_Get' Method? If Not, How to Create My Own