rails How to migration find_all_by_ - ruby-on-rails

Hi I migrate an app from Rails 2 to Rails 7.04.
I don't see how to rewrite :
self.accepted_roles.find_all_by_name(role_name).any? { |role| role.users }
users = self.accepted_roles.find_all_by_name(role_name).collect { |role| role.users }
users.flatten.uniq if users
I think self.roles.where("name="role_name).find_each but .any? and .collect
I don't find Rails 2 documentation.
Help is welcome

I think that .where() is what you are looking for.

Related

how to reject from an AR association where a specific condition exists

I'd like to remove items from the following association (where a site_placement has a native_ad_placement.ad_type == "video") and have the following code but this doesn't seem to work
# not an array but an association
#sites.each do |site|
site.site_placements.reject { |sp| (sp.native_ad_placement.ad_type == "video") }
end
How could I achieve this? I'm using Rails 3.2.
You should use .reject! instead of .reject.
But really, you shouldn't use reject at all. If I am not wrong, you can totally achieve the same thing at querying level, and it is even much more effective. Something like below:
Site.includes(site_placements: [: native_ad_placement]).where.not(native_ad_placements: { ad_type: "video" })

Cannot Define Attribute in Create method Rails

In rails 4.2.4, I can successfully execute this line of code.
Model.Create!(name: "Bob")
In Rails 4.2.5, this does nothing and leaves me with a null field in the database. To get past this, I must do something like this...
s = Model.Create!()
s.name = "Bob"
s.save!
Does anyone know why the first method doesn't work? Has rails been updated to something different? I haven't been able to find a solution for this. Thanks in advance.
Difference Between Model.create() and Model.new()
Model.create() It will create and save empty columns DB, if its not "validated".
Model.new() It will create empty table but not saves it in DB. Until will not be saved.
Example:
u = User.new
u.first_name = 'Joe'
u.last_name = 'Doe'
u.save #this saves DB.
Here is good Examples

Active Admin rails, how to escape html before save?

i'm new of rails and since few days i'm playing with active admin.
I'm using it to manage data of an old legacy system.
I have a issue: i need to save an html string into table, but escaped and i dont find a solution for this.
Example, i want to save this
<b>Ciao</b> mondo!
Like that
<p>Ciao <b>Mondo!</p>
With this block of code i can show it correctly in index page, but when i try to add new or edit it doesn't excape correctly
index do
column :label
column (:value_it) { |e| raw(e.value_it) }
column (:value_en) { |e| raw(e.value_en) }
column (:value_es) { |e| raw(e.value_es) }
default_actions
end
Thanks
irb(main):001:0> CGI.escapeHTML '<b>Ciao</b> mondo!'
=> "<b>Ciao</b> mondo!"
irb(main):002:0> CGI.unescapeHTML( CGI.escapeHTML '<b>Ciao</b> mondo!' )
=> "<b>Ciao</b> mondo!"
plug it into before_save hook on the model and you're good to go

Converting Rails model to SQL insert Query?

Is there a way to convert a Rails model into an insert query?
For instance, if I have a model like:
m = Model.new
m.url = "url"
m.header = "header"
How can I get the corresponding SQL query ActiveRecord would generate if I did m.save?
I want to get: "INSERT INTO models(url, header) VALUES('url', 'header')" if possible.
Note: I don't want to actually save the model and get the query back (from log file, etc). I want to get the query IF I chose to save it.
On Rails 4.1, I found the below code snippet working:
record = Post.new(:title => 'Yay', :body => 'This is some insert SQL')
record.class.arel_table.create_insert
.tap { |im| im.insert(record.send(
:arel_attributes_with_values_for_create,
record.attribute_names)) }
.to_sql
Thanks to https://coderwall.com/p/obrxhq/how-to-generate-activerecord-insert-sql
Tested in Rails 3.2.13: I think I got it right this time, it definitely does not persist to the db this time. It also won't fire validations or callbacks so anything they change won't be in the results unless you've called them some other way.
Save this in lib as insert_sqlable.rb and you can then
#in your models or you can send it to ActiveRecord::Base
include InsertSqlable
Then it is model.insert_sql to see it.
#lib/insert_sqlable
module InsertSqlable
def insert_sql
values = arel_attributes_values
primary_key_value = nil
if self.class.primary_key && Hash === values
primary_key_value = values[values.keys.find { |k|
k.name == self.class.primary_key
}]
if !primary_key_value && connection.prefetch_primary_key?(self.class.table_name)
primary_key_value = connection.next_sequence_value(self.class.sequence_name)
values[self.class.arel_table[self.class.primary_key]] = primary_key_value
end
end
im = self.class.arel_table.create_insert
im.into self.class.arel_table
conn = self.class.connection
substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
binds = substitutes.map do |arel_attr, value|
[self.class.columns_hash[arel_attr.name], value]
end
substitutes.each_with_index do |tuple, i|
tuple[1] = conn.substitute_at(binds[i][0], i)
end
if values.empty? # empty insert
im.values = Arel.sql(self.class.connectionconnection.empty_insert_statement_value)
else
im.insert substitutes
end
conn.to_sql(im,binds)
end
end
It turns out the code is in ActiveRecord::Relation and not ActiveRecord::Persistence. The only significant change is the last line which generates the sql instead of performing it.
If you dont want to save the model you call m.destroy when you are done with the object.
You can log the sql query by debugging it like this
Rails.logger.debug "INSERT INTO models(url, header) VALUES(#{m.url}, #{m.header}).inspect
After search a lot over the Internet and forums, I think I found a better solution for your problem: just requires two line of code.
I found a good gem that do exactly what you want, but this gem only works for Rails 3.2 and older. I talked with author and he doesn't want support this gem anymore. So I discovered by myself how to support Rails 4.0 and now I'm maintaining this gem.
Download the "models-to-sql-rails" gem here, supporting Rails 4.0 and older.
With this gem, you can easily do the following. (the examples inside values are just a joke, you will get the correct values when using it in your object).
For objects:
object.to_sql_insert
# INSERT INTO modelName (field1, field2) VALUES ('Wow, amaze gem', 'much doge')
For array of objets:
array_of_objects.to_sql_insert
# INSERT INTO modelName (field1, field2) VALUES ('Awesome doge', "im fucking cop")
# INSERT INTO modelName (field1, field2) VALUES ('much profit', 'much doge')
# (...)
Just see the Github of this project and you'll find how to install and use this wonderful gem.

Reusing named_scope to define another named_scope

The problem essence as I see it
One day, if I'm not mistaken, I have seen an example of reusing a named_scope to define another named_scope. Something like this (can't remember the exact syntax, but that's exactly my question):
named_scope :billable, :conditions => ...
named_scope :billable_by_tom, :conditions => {
:billable => true,
:user => User.find_by_name('Tom')
}
The question is: what is the exact syntax, if it's possible at all? I can't find it back, and Google was of no help either.
Some explanations
Why I actually want it, is that I'm using Searchlogic to define a complex search, which can result in an expression like this:
Card.user_group_managers_salary_greater_than(100)
But it's too long to be put everywhere. Because, as far as I know, Searchlogic simply defines named_scopes on the fly, I would like to set a named_scope on the Card class like this:
named_scope from_big_guys, { user_group_managers_salary_greater_than(100) }
- this is where I would use that long Searchlogic method inside my named_scope. But, again, what would be the syntax? Can't figure it out.
Resume
So, is named_scope nesting (and I do not mean chaining) actually possible?
You can use proxy_options to recycle one named_scope into another:
class Thing
#...
named_scope :billable_by, lambda{|user| {:conditions => {:billable_id => user.id } } }
named_scope :billable_by_tom, lambda{ self.billable_by(User.find_by_name('Tom').id).proxy_options }
#...
end
This way it can be chained with other named_scopes.
I use this in my code and it works perfectly.
I hope it helps.
Refer to this question raised time ago here at SO.
There is a patch at lighthouse to achieve your requirement.
Rails 3+
I had this same question and the good news is that over the last five years the Rails core team has made some good strides in the scopes department.
In Rails 3+ you can now do this, as you'd expect:
scope :billable, where( due: true )
scope :billable_by_tom, -> { billable.where( user: User.find_by_name('Tom') ) }
Invoice.billable.to_sql #=> "... WHERE due = 1 ..."
Invoice.billiable_by_tom.to_sql #=> "... WHERE due = 1 AND user_id = 5 ..."
FYI, Rails 3+ they've renamed named_scope to just scope. I'm also using Ruby 1.9 syntax.
Bonus Round: Generic Scope.
If there are multiple people that are "billable" besides just "Tom" then it might be useful to make a generic scope that accepts a name param that gets passed into the block:
scope :billable_by, lambda { |name| billable.where( user: User.find_by_name( name ) ) }
Then you can just call it with:
Invoice.billable_by( "Tom" ).to_sql #=> "... WHERE due = 1 AND user_id = 5 ..."
Btw, you can see I used the older lambda syntax in the bonus round. That's because I think the new syntax looks atrocious when you're passing a param to it: ->( name ) { ... }.
Chain Scopes.
Why not have a scope for stuff just by Tom in general, like:
scope :by_tom, where( user: User.find_by_name('Tom') )
And then you can get those records that are "billable by Tom" with:
Record.billable.by_tom
You can use a method to combine some named_scope like :
def self.from_big_guys
self.class.user_group_managers_salary_greater_than(100)
end
This feature is add on Rails 3 with new syntax (http://m.onkey.org/2010/1/22/active-record-query-interface)

Resources