I have a "grouped_collection_select" for a "branch" field, in combination with a "sector" field. Sector has_many branches and branch belongs_to sector:
<%= f.grouped_collection_select(:branch, current_user.company.sectors.order(:sector), :branches, :sector, :id, :branch, include_blank: true) %>
This works, but the ":branches" shows all branches and should only show the branches of the current_user.company, just like the sectord. But when I change ":branches" into "current_user.company.branches.order(:branch)", I get an error:
(eval):1: syntax error, unexpected $end group.#<ActiveRecord
What am I doing wrong here? Thanks!
For clarity (and semantics) set that collection in your controller to use in your view:
#sectors = current_user.company.sectors.order(:sector)
...or if you want to limit the branches that are showing for each sector by user, you'd probably want to build the collection based on the user's branches. One example:
#sectors = current_user.company.branches.collect{|b| b.sector}.uniq
Then assuming you want to set the branch_id AND a sector has a name attribute AND the branch has a name attribute, this should work:
<%= f.grouped_collection_select(:branch_id, #sectors, :branches, :name, :id, :name, :include_blank=>true)
#:branch_id is the attribute you will be setting on the form_builder's object.
##sectors is the collection of objects for the groups.
#:branches is the method that will be called on each sector object.
#:name is the method that will be called on each sector object to label the group.
#:id is the method that will be called on each branch to set the option's value.
#:name is the method that will be called on each branch to set the option's label.
Related
So I'm having a little difficulty using Rails to query some data.
I have two models and I'm attempting to join one on to the other. My issue arises using a group by method. Both models have the same attribute name and this is causing an ambiguous column name error. My query is:
Photo.joins(:votes).group(:photo_id, :image, :title, :bytes, :user_id, :public_id).order("count_all desc").limit(10).count
How can I choose which model that the group by attributes use?
You can specify the table name like this:
Photo.joins(:votes)
.group(:photo_id, :image, :title, :bytes, 'photos.user_id', :public_id)
.order("count_all desc")
.limit(10)
.count
Assuming user_id is the ambiguous column name and photos is the actual tablename.
I recently switched my project to postgres and it is messing up my select forms in small but annoying manner.
I have 2 select fields,
<%= f.collection_select :state, State.all, :value, :name, {include_blank: '- Select State -'} %>
<%= f.grouped_collection_select :area, State.all, :areas, :name, :value, :name, {include_blank: '- Select Area -'} %>
The first select field contains a bunch of States. The second select field contains a bunch of Areas/Districts grouped(optgroup) by States.
Using "seeds.rb", I inserted all the relevant data. Everything was inserted in alphabetical order.
In SQLite3, the select results are all presented alphabetically.
However, when i swapped over to Postgrsql, my :area select is now presenting its options in reverse alphabetical order which is terrible for user experience.
I have also tested the following scenario with the following query in the rails console:
State.find("Texas").areas
SQLite3 results:
[Area A, Area B, Area C]
Postgres results:
[Area C, Area B, Area A]
Is there any way i can get the same results as SQLite3 with Postgres while still using it with my "f.group_collection_select"?
You can specify the default order in the has_many relationship.
class State < ActiveRecord::Base
has_many :areas, -> { order("areas.name ASC") }
end
use order clause on name or id whichever appropriate(I'd prefer name) with default scope for Area.
default_scope { order(:name :asc) }
You can do this by defining a scope in your Area model
See : Grouped Collection Select Alphabetical Order Rails
In Rails, I get a hash using includes:
<% #teste = UserProfile.includes(:mobile_models).group(:name).count %>
The problem is that includes generates a hash like the following:
{nil=>4774, "2610"=>7, "2626"=>4, "2630"=>5, "2760"=>4, "3250"=>3, "355"=>5, "3I607 BlackJack"=>5, "5230"=>13, "5235"=>4, "5310"=>5, "5500"=>5, "5800 Xpress Music"=>16, "6020"=>4, "6120c"=>4, "6131"=>4, "7210"=>5, "A1200r"=>5, "A1900"=>5, "AIKO 70"=>5, "B3410W Ch#t"=>4, "beTouch E100"=>4, "BlackBerry 8320 (Curve)"=>10,....
In my database, I don't find any mobile record with the name "nil". Checking my database, I can't find what might be producing this nil.
The other goal is to sum all values, like this:
<%= sum = #teste.values.sum %>
But when I do this, the 'nil' is added too.
---Update
models/UserProfile
class UserProfile < ActiveRecord::Base
has_and_belongs_to_many :mobile_models, join_table: 'user_profiles_mobile_models', order: 'name'
models/MobileModel
class MobileModel < ActiveRecord::Base
belongs_to :mobile_maker
Because you are grouping by :name, some of the MobileModel or UserProfile objects have the name attribute set to nil. You will need to check both as without seeing the model definition, I can't tell which model has the :name property you are grouping on. If you can share the model code, I can be more explicit.
If both models have a name attribute, you can be more explicit in your group statement:
UserProfile.includes(:mobile_models).group('mobile_models.name')
or...
UserProfile.includes(:mobile_models).group('user_profiles.name')
Also, if a number of your users do not have any mobile_models to include, I believe they will get dumped into the nil grouping as well.
You are getting that hash because of group(:name).
That means you have 4774 records who's name is nil.
I have a boolean field that has a default value of false in the joining table of a has many through relationship: tags and tag lists.
add_column :taggings, :tag_visible, :boolean, :default => false
The theory is that a tag list can have many tags (and vice versa) but a tags visibility can be turned off/on per tag list.
This is also part of a nested resource: Document has_one :tag_list
For the most part this is all working. The default value is set on creation and I am updating each instance with an ajax call.
However when I update the document which includes the tag_list as a token input field it resets all of the tagging's visibility back to false regardless of what it was previously.
Any leads would be greatly appreciated.
Turns out that in my tags token_input setter inside my tag_list model I was deleting and recreating a new record in the tagging model instead of updating it.
old code:
self.taggings = Tag.ids_from_tokens(tokens, user_id).each_with_index.map {|t,i| Tagging.new(:tag_id => t, :tag_colour => tag_colours[i % tag_colours.size]) }
fix:
self.tag_ids = Tag.ids_from_tokens(tokens, user_id)
self.taggings.each_with_index {|t,i| t.update_attributes(:tag_colour => tag_colours[i % tag_colours.size]) }
I'd like to update a massive set of document on an hourly basis.
Here's the
fairly simple Model:
class Article
include Mongoid::Document
field :article_nr, :type => Integer
field :vendor_nr, :type => Integer
field :description, :type => String
field :ean
field :stock
field :ordered
field :eta
so every hour i get a fresh stock list, where :stock,:ordered and :eta "might" have changed
and i need to update them all.
Edit:
the stocklist contains just
:article_nr, :stock, :ordered, :eta
wich i parse to a hash
In SQL i would have taken the route to foreign keying the article_nr to a "stock" table, dropping the whole stock table, and running a "collection.insert" or something alike
But that approach seems not to work with mongoid.
Any hints? i can't get my head around collection.update
and changing the foreign key on belongs_to and has_one seems not to work
(tried it, but then Article.first.stock was nil)
But there has to be a faster way than iterating over the stocklist array of hashes and doing
something like
Article.where( :article_nr => stocklist['article_nr']).update( stock: stocklist['stock'], eta: stocklist['eta'],orderd: stocklist['ordered'])
UPDATING
You can atomically update multiple documents in the database via a criteria using Criteria#update_all. This will perform an atomic $set on all the attributes passed to the method.
# Update all people with last name Oldman with new first name.
Person.where(last_name: "Oldman").update_all(
first_name: "Pappa Gary"
)
Now I can understood a bit more. You can try to do something like that, assuming that your article nr is uniq.
class Article
include Mongoid::Document
field :article_nr
field :name
key :article_nr
has_many :stocks
end
class Stock
include Mongoid::Document
field :article_id
field :eta
field :ordered
belongs_to :article
end
Then you when you create stock:
Stock.create(:article_id => "123", :eta => "200")
Then it will automaticly get assign to article with article_nr => "123"
So you can always call last stock.
my_article.stocks.last
If you want to more precise you add field :article_nr in Stock, and then :after_save make new_stock.article_id = new_stock.article_nr
This way you don't have to do any updates, just create new stocks and they always will be put to correct Article on insert and you be able to get latest one.
If you can extract just the stock information into a separate collection (perhaps with a has_one relationship in your Article), then you can use mongoimport with the --upsertFields option, using article_nr as your upsertField. See http://www.mongodb.org/display/DOCS/Import+Export+Tools.